addMusic.tsx 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  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. NDataTable,
  8. NFormItem,
  9. NIcon,
  10. NImage,
  11. NInput,
  12. NInputNumber,
  13. NSelect,
  14. NSpace,
  15. NStep,
  16. NSteps,
  17. useDialog,
  18. useMessage
  19. } from 'naive-ui'
  20. import Pagination from '@components/pagination'
  21. import { getMapValueByKey, getSelectDataFromObj } from '@/utils/objectUtil'
  22. import {
  23. musicSheetAvailableType,
  24. musicSheetPaymentType,
  25. musicSheetSourceType,
  26. musicSheetType
  27. } from '@/utils/constant'
  28. import {musicSheetApplicationExtendSaveBatch, musicSheetApplicationExtendTagList, musicSheetPage} from '@views/music-library/api'
  29. import deepClone from '@/utils/deep.clone'
  30. import { getOwnerName } from '@views/music-library/musicUtil'
  31. import TheTooltip from "@components/TheTooltip";
  32. export default defineComponent({
  33. name: 'klx-addMusic',
  34. props: {
  35. appId: {
  36. type: String,
  37. required: true
  38. },
  39. subjectList: {
  40. type: Array,
  41. default: () => []
  42. },
  43. musicSheetTagList: {
  44. type: Array,
  45. default: () => []
  46. }
  47. },
  48. emits: ['close', 'getList'],
  49. setup(props, { slots, attrs, emit }) {
  50. const dialogs = useDialog()
  51. const message = useMessage()
  52. const state = reactive({
  53. loading: false,
  54. pagination: {
  55. page: 1,
  56. rows: 5,
  57. pageTotal: 0
  58. },
  59. stepPagination: {
  60. page: 1,
  61. rows: 5,
  62. pageTotal: 0
  63. },
  64. searchForm: {
  65. keyword: null,
  66. musicSheetType: null,
  67. subjectId: null,
  68. sourceType: null
  69. },
  70. subjectList: [] as any,
  71. showAdd: false,
  72. currentStep: 1,
  73. dataList: [],
  74. selectRowData: [] as any, // 选择的数据列表
  75. musicSheetCategories: [] as any,
  76. musicSheetTagList: [] as any,
  77. globalMusicTagIds: [] as any, //曲目标签
  78. globalPaymentType: null as any, //收费方式
  79. globalMusicPrice: null as any, //曲目价格
  80. globalAvailableType: null as any, //可用途径
  81. globalTopFlag: null as any, //是否置顶
  82. globalExquisiteFlag: null as any, //精品乐谱
  83. globalStartSortNum: null as any // 排序起始值
  84. })
  85. onMounted(async () => {
  86. state.loading = true
  87. state.subjectList = props.subjectList
  88. // state.musicSheetTagList = props.musicSheetTagList
  89. // 加载曲目标签
  90. try {
  91. const {data} = await musicSheetApplicationExtendTagList({applicationId: props.appId})
  92. if (data && data.length > 0) {
  93. data.forEach((item: any) => {
  94. state.musicSheetTagList.push({
  95. ...item,
  96. label: item.name,
  97. value: item.id
  98. })
  99. })
  100. }
  101. } catch (err) {
  102. }
  103. await getList()
  104. })
  105. const getList = async () => {
  106. try {
  107. state.loading = true
  108. const { data } = await musicSheetPage({
  109. ...state.pagination,
  110. ...state.searchForm,
  111. addAppId: props.appId
  112. })
  113. state.pagination.pageTotal = Number(data.total)
  114. state.dataList = data.rows || []
  115. } catch {}
  116. state.loading = false
  117. }
  118. const saveForm = ref()
  119. const onSearch = () => {
  120. saveForm.value?.submit()
  121. }
  122. const onBtnReset = () => {
  123. saveForm.value?.reset()
  124. }
  125. const onSubmit = () => {
  126. state.pagination.page = 1
  127. getList()
  128. }
  129. const onSave = async () => {
  130. if (state.selectRowData.length == 0) {
  131. message.error('未选择曲目')
  132. return
  133. }
  134. const params = [] as any[]
  135. for (let i = 0; i < state.selectRowData.length; i++) {
  136. const item = state.selectRowData[i]
  137. if (!item.musicTagIds || item.musicTagIds.length == 0) {
  138. message.error('曲目标签不能为空')
  139. return
  140. }
  141. if (!item.paymentType) {
  142. message.error('收费方式不能为空')
  143. return
  144. }
  145. if (!item.paymentType.includes('CHARGE')) {
  146. item.musicPrice = 0
  147. } else {
  148. if (item.musicPrice === null || item.musicPrice === undefined || item.musicPrice==='') {
  149. message.error('曲目价格不能为空')
  150. return
  151. }
  152. }
  153. if (!item.availableType) {
  154. message.error('可用途径不能为空')
  155. return
  156. }
  157. if (typeof item.topFlag !== 'boolean') {
  158. message.error('是否置顶不能为空')
  159. return
  160. }
  161. if (typeof item.exquisiteFlag !== 'boolean') {
  162. message.error('是否精品不能为空')
  163. return
  164. }
  165. if (item.sortNo === null || item.sortNo === undefined || item.sortNo === '') {
  166. message.error('排序号不能为空')
  167. return
  168. }
  169. params.push({
  170. ...item,
  171. musicSheetId: item.id,
  172. applicationId: props.appId,
  173. paymentType: item.paymentType.join(','),
  174. musicTagIds: item.musicTagIds.join(','),
  175. id: null
  176. })
  177. }
  178. const res = (await musicSheetApplicationExtendSaveBatch(params)) as any
  179. if (res && res.code == '200') {
  180. message.success(`添加成功`)
  181. emit('getList')
  182. emit('close')
  183. }
  184. }
  185. const columnsField = [
  186. {
  187. type: 'selection'
  188. },
  189. {
  190. title: '曲目编号',
  191. key: 'id'
  192. },
  193. {
  194. title: '封面图',
  195. key: 'titleImg',
  196. render(row: any) {
  197. return <NImage width={40} height={40} src={row.musicCover} />
  198. }
  199. },
  200. {
  201. title: '声部',
  202. key: 'subjectNames',
  203. render: (row: any) => {
  204. return <TheTooltip content={row.subjectNames}/>
  205. }
  206. },
  207. {
  208. title: '曲目名称',
  209. key: 'name'
  210. },
  211. {
  212. title: '音乐人',
  213. key: 'composer'
  214. },
  215. {
  216. title: '曲目类型',
  217. key: 'musicSheetType',
  218. render: (row: any) => {
  219. return (
  220. <div>
  221. {getMapValueByKey(row.musicSheetType, new Map(Object.entries(musicSheetType)))}
  222. </div>
  223. )
  224. }
  225. },
  226. {
  227. title: '作者属性',
  228. key: 'sourceType',
  229. render(row: any) {
  230. return getMapValueByKey(row.sourceType, new Map(Object.entries(musicSheetSourceType)))
  231. }
  232. },
  233. {
  234. title: '所属人',
  235. key: 'userName',
  236. render: (row: any) => {
  237. return <TheTooltip content={getOwnerName(row.musicSheetExtend, row.sourceType)} />
  238. }
  239. }
  240. ]
  241. const columns = (): any => {
  242. return columnsField
  243. }
  244. const stepColumns = (): DataTableColumns => {
  245. const field = deepClone(columnsField)
  246. field.splice(0, 1)
  247. field.push({
  248. title(column: any) {
  249. return (
  250. <NSpace>
  251. 曲目标签
  252. <NButton
  253. type="primary"
  254. size="small"
  255. text
  256. onClick={() => {
  257. dialogs.create({
  258. title: '请选择曲目标签',
  259. showIcon: false,
  260. content: () => {
  261. return h(
  262. 'div',
  263. {
  264. class: 'flex flex-col justify-center items-center text-14px'
  265. },
  266. [
  267. h(NSelect, {
  268. onUpdateValue(v) {
  269. state.globalMusicTagIds = v
  270. },
  271. multiple: true,
  272. clearable: true,
  273. options: state.musicSheetTagList
  274. })
  275. ]
  276. )
  277. },
  278. positiveText: '确定',
  279. negativeText: '取消',
  280. onPositiveClick: () => {
  281. for (let i = 0; i < state.selectRowData.length; i++) {
  282. const item = state.selectRowData[i]
  283. item.musicTagIds = state.globalMusicTagIds
  284. }
  285. }
  286. })
  287. }}
  288. >
  289. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  290. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  291. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  292. <path
  293. 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"
  294. fill="currentColor"
  295. ></path>
  296. </svg>
  297. </NIcon>
  298. </NButton>
  299. </NSpace>
  300. )
  301. },
  302. key: 'musicTagIds',
  303. width:'180px',
  304. render: (row: any) => {
  305. // })
  306. return (
  307. <NSelect
  308. placeholder="请选择曲目标签"
  309. value={row.musicTagIds}
  310. options={state.musicSheetTagList}
  311. clearable
  312. multiple
  313. maxTagCount={1}
  314. onUpdateValue={(value) => {
  315. row['musicTagIds'] = value
  316. }}
  317. />
  318. )
  319. }
  320. })
  321. field.push({
  322. title(column: any) {
  323. return (
  324. <NSpace>
  325. 收费方式
  326. <NButton
  327. type="primary"
  328. size="small"
  329. text
  330. onClick={() => {
  331. dialogs.create({
  332. title: '请选择收费方式',
  333. showIcon: false,
  334. content: () => {
  335. return h(
  336. 'div',
  337. {
  338. class: 'flex flex-col justify-center items-center text-14px'
  339. },
  340. [
  341. h(NSelect, {
  342. value: state.globalPaymentType,
  343. onUpdateValue(v) {
  344. state.globalPaymentType = v
  345. const free = 'FREE'
  346. if (state.globalPaymentType[state.globalPaymentType.length - 1] == free) {
  347. state.globalPaymentType = [free]
  348. return
  349. }
  350. if (state.globalPaymentType.length > 1 && state.globalPaymentType.includes(free)) {
  351. state.globalPaymentType.splice(state.globalPaymentType.indexOf(free), 1)
  352. }
  353. },
  354. multiple: true,
  355. clearable: true,
  356. options: getSelectDataFromObj(musicSheetPaymentType)
  357. }
  358. )
  359. ]
  360. )
  361. },
  362. positiveText: '确定',
  363. negativeText: '取消',
  364. onPositiveClick: () => {
  365. for (let i = 0; i < state.selectRowData.length; i++) {
  366. const item = state.selectRowData[i]
  367. item.paymentType = state.globalPaymentType
  368. if (!state.globalPaymentType.includes("CHARGE")) {
  369. item.musicPrice = 0
  370. item.musicPriceDisable = true
  371. }
  372. }
  373. }
  374. })
  375. }}
  376. >
  377. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  378. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  379. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  380. <path
  381. 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"
  382. fill="currentColor"
  383. ></path>
  384. </svg>
  385. </NIcon>
  386. </NButton>
  387. </NSpace>
  388. )
  389. },
  390. key: 'paymentType',
  391. width:'180px',
  392. render: (row: any) => {
  393. return (
  394. <NSelect
  395. placeholder="请选择收费方式"
  396. value={row.paymentType as []}
  397. options={getSelectDataFromObj(musicSheetPaymentType)}
  398. clearable
  399. multiple
  400. maxTagCount={1}
  401. onUpdate:value={(value) => {
  402. row.paymentType = value
  403. const free = 'FREE'
  404. if (row.paymentType[row.paymentType.length - 1] == free) {
  405. row.paymentType = [free]
  406. } else if (row.paymentType.length > 1 && row.paymentType.includes(free)) {
  407. row.paymentType.splice(row.paymentType.indexOf(free), 1)
  408. }
  409. if (!row.paymentType.includes("CHARGE")) {
  410. row.musicPrice = 0
  411. }
  412. }}
  413. />
  414. )
  415. }
  416. })
  417. field.push({
  418. title(column: any) {
  419. return (
  420. <NSpace>
  421. 曲目价格
  422. <NButton
  423. type="primary"
  424. size="small"
  425. text
  426. onClick={() => {
  427. dialogs.create({
  428. title: '请输入曲目价格',
  429. showIcon: false,
  430. content: () => {
  431. return h(
  432. 'div',
  433. {
  434. class: 'flex flex-col justify-center items-center text-14px'
  435. },
  436. [
  437. // icon
  438. h(NInputNumber, {
  439. onUpdateValue(v) {
  440. state.globalMusicPrice = v
  441. },
  442. min: 0,
  443. max: 9999
  444. })
  445. ]
  446. )
  447. },
  448. positiveText: '确定',
  449. negativeText: '取消',
  450. onPositiveClick: () => {
  451. if (state.globalMusicPrice) {
  452. for (let i = 0; i < state.selectRowData.length; i++) {
  453. const item = state.selectRowData[i]
  454. if (item.paymentType.includes("CHARGE")) { // 只修改包含单曲收费,则价格为0
  455. item.musicPrice = state.globalMusicPrice
  456. }
  457. }
  458. }
  459. }
  460. })
  461. }}
  462. >
  463. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  464. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  465. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  466. <path
  467. 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"
  468. fill="currentColor"
  469. ></path>
  470. </svg>
  471. </NIcon>
  472. </NButton>
  473. </NSpace>
  474. )
  475. },
  476. key: 'musicPrice',
  477. render: (row: any) => {
  478. return h(NInputNumber, {
  479. value: row.musicPrice,
  480. min: 0,
  481. max: 9999,
  482. disabled: !row.paymentType?.includes('CHARGE'),
  483. onUpdateValue(value: any) {
  484. row['musicPrice'] = value
  485. }
  486. })
  487. }
  488. })
  489. field.push({
  490. title(column: any) {
  491. return (
  492. <NSpace>
  493. 可用途径
  494. <NButton
  495. type="primary"
  496. size="small"
  497. text
  498. onClick={() => {
  499. dialogs.create({
  500. title: '请选择可用途径',
  501. showIcon: false,
  502. content: () => {
  503. return h(
  504. 'div',
  505. {
  506. class: 'flex flex-col justify-center items-center text-14px'
  507. },
  508. [
  509. // icon
  510. h(NSelect, {
  511. onUpdateValue(v) {
  512. state.globalAvailableType = v
  513. },
  514. clearable: true,
  515. options: getSelectDataFromObj(musicSheetAvailableType)
  516. })
  517. ]
  518. )
  519. },
  520. positiveText: '确定',
  521. negativeText: '取消',
  522. onPositiveClick: () => {
  523. for (let i = 0; i < state.selectRowData.length; i++) {
  524. const item = state.selectRowData[i]
  525. item.availableType = state.globalAvailableType
  526. }
  527. }
  528. })
  529. }}
  530. >
  531. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  532. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  533. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  534. <path
  535. 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"
  536. fill="currentColor"
  537. ></path>
  538. </svg>
  539. </NIcon>
  540. </NButton>
  541. </NSpace>
  542. )
  543. },
  544. key: 'availableType',
  545. render: (row: any) => {
  546. return (
  547. <NSelect
  548. placeholder="请选择可用途径"
  549. value={row.availableType}
  550. options={getSelectDataFromObj(musicSheetAvailableType)}
  551. onUpdateValue={(value) => {
  552. row['availableType'] = value
  553. }}
  554. clearable
  555. />
  556. )
  557. }
  558. })
  559. field.push({
  560. title(column: any) {
  561. return (
  562. <NSpace>
  563. 是否置顶
  564. <NButton
  565. type="primary"
  566. size="small"
  567. text
  568. onClick={() => {
  569. dialogs.create({
  570. title: '请选择是否置顶',
  571. showIcon: false,
  572. content: () => {
  573. return h(
  574. 'div',
  575. {
  576. class: 'flex flex-col justify-center items-center text-14px'
  577. },
  578. [
  579. // icon
  580. h(NSelect, {
  581. onUpdateValue(v) {
  582. state.globalTopFlag = v
  583. },
  584. options: [
  585. {
  586. label: '是',
  587. value: true
  588. },
  589. {
  590. label: '否',
  591. value: false
  592. }
  593. ] as any
  594. })
  595. ]
  596. )
  597. },
  598. positiveText: '确定',
  599. negativeText: '取消',
  600. onPositiveClick: () => {
  601. for (let i = 0; i < state.selectRowData.length; i++) {
  602. const item = state.selectRowData[i]
  603. item.topFlag = state.globalTopFlag
  604. }
  605. }
  606. })
  607. }}
  608. >
  609. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  610. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  611. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  612. <path
  613. 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"
  614. fill="currentColor"
  615. ></path>
  616. </svg>
  617. </NIcon>
  618. </NButton>
  619. </NSpace>
  620. )
  621. },
  622. key: 'topFlag',
  623. render: (row: any) => {
  624. return (
  625. <NSelect
  626. placeholder="请选择是否置顶"
  627. value={row.topFlag}
  628. options={
  629. [
  630. {
  631. label: '是',
  632. value: true
  633. },
  634. {
  635. label: '否',
  636. value: false
  637. }
  638. ] as any
  639. }
  640. clearable
  641. onUpdateValue={(value) => {
  642. row['topFlag'] = value
  643. }}
  644. />
  645. )
  646. }
  647. })
  648. field.push({
  649. title(column: any) {
  650. return (
  651. <NSpace>
  652. 是否精品
  653. <NButton
  654. type="primary"
  655. size="small"
  656. text
  657. onClick={() => {
  658. dialogs.create({
  659. title: '请选择是否精品',
  660. showIcon: false,
  661. content: () => {
  662. return h(
  663. 'div',
  664. {
  665. class: 'flex flex-col justify-center items-center text-14px'
  666. },
  667. [
  668. // icon
  669. h(NSelect, {
  670. onUpdateValue(v) {
  671. state.globalExquisiteFlag = v
  672. },
  673. options: [
  674. {
  675. label: '是',
  676. value: true
  677. },
  678. {
  679. label: '否',
  680. value: false
  681. }
  682. ] as any
  683. })
  684. ]
  685. )
  686. },
  687. positiveText: '确定',
  688. negativeText: '取消',
  689. onPositiveClick: () => {
  690. for (let i = 0; i < state.selectRowData.length; i++) {
  691. const item = state.selectRowData[i]
  692. item.exquisiteFlag = state.globalExquisiteFlag
  693. }
  694. }
  695. })
  696. }}
  697. >
  698. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  699. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  700. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  701. <path
  702. 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"
  703. fill="currentColor"
  704. ></path>
  705. </svg>
  706. </NIcon>
  707. </NButton>
  708. </NSpace>
  709. )
  710. },
  711. key: 'exquisiteFlag',
  712. render: (row: any) => {
  713. return (
  714. <NSelect
  715. placeholder="请选择是否精品"
  716. value={row.exquisiteFlag}
  717. onUpdateValue={(value) => {
  718. row['exquisiteFlag'] = value
  719. }}
  720. options={
  721. [
  722. {
  723. label: '是',
  724. value: true
  725. },
  726. {
  727. label: '否',
  728. value: false
  729. }
  730. ] as any
  731. }
  732. clearable
  733. />
  734. )
  735. }
  736. })
  737. field.push({
  738. title(column: any) {
  739. return (
  740. <NSpace>
  741. 排序
  742. <NButton
  743. type="primary"
  744. size="small"
  745. text
  746. onClick={() => {
  747. dialogs.create({
  748. title: '请输入排序起始值',
  749. showIcon: false,
  750. content: () => {
  751. return h(
  752. 'div',
  753. {
  754. class: 'flex flex-col justify-center items-center text-14px'
  755. },
  756. [
  757. // icon
  758. h(NInputNumber, {
  759. onUpdateValue(v) {
  760. state.globalStartSortNum = v
  761. },
  762. min: 0,
  763. max: 9999
  764. })
  765. ]
  766. )
  767. },
  768. positiveText: '确定',
  769. negativeText: '取消',
  770. onPositiveClick: () => {
  771. for (let i = 0; i < state.selectRowData.length; i++) {
  772. const item = state.selectRowData[i]
  773. item.sortNo = state.globalStartSortNum + i
  774. }
  775. }
  776. })
  777. }}
  778. >
  779. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  780. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  781. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  782. <path
  783. 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"
  784. fill="currentColor"
  785. ></path>
  786. </svg>
  787. </NIcon>
  788. </NButton>
  789. </NSpace>
  790. )
  791. },
  792. key: 'sortNo',
  793. fixed: 'right',
  794. width: 150,
  795. render: (row: any) => {
  796. return h(NInputNumber, {
  797. value: row.sortNo,
  798. min: 0,
  799. max: 9999,
  800. onUpdateValue(value: any) {
  801. row.sortNo = value
  802. }
  803. })
  804. }
  805. })
  806. field.push({
  807. title: '操作',
  808. key: 'operation',
  809. fixed: 'right',
  810. render(row: any) {
  811. return (
  812. <NSpace>
  813. <NButton
  814. type="primary"
  815. size="small"
  816. text
  817. //v-auth="musicSheet/update1602302618558099458"
  818. onClick={() => {
  819. dialogs.warning({
  820. title: '提示',
  821. content: `是否删除该数据?`,
  822. positiveText: '确定',
  823. negativeText: '取消',
  824. onPositiveClick: async () => {
  825. try {
  826. const index = state.selectRowData.findIndex((item: any) => {
  827. if (item.id == row.id) {
  828. return true
  829. }
  830. })
  831. if (index > -1) {
  832. state.selectRowData.splice(index, 1)
  833. }
  834. const index1 = checkedRowKeysRef.value.findIndex((item: any) => {
  835. if (item == row.id) {
  836. return true
  837. }
  838. })
  839. if (index1 > -1) {
  840. checkedRowKeysRef.value.splice(index, 1)
  841. }
  842. } catch {}
  843. }
  844. })
  845. }}
  846. >
  847. 移除
  848. </NButton>
  849. </NSpace>
  850. )
  851. }
  852. })
  853. return field
  854. }
  855. const checkedRowKeysRef = ref<DataTableRowKey[]>([])
  856. const handleCheck = (rowKeys: DataTableRowKey[]) => {
  857. checkedRowKeysRef.value = rowKeys
  858. // 添加行更新值
  859. state.dataList.forEach((next: any) => {
  860. if (checkedRowKeysRef.value.includes(next.id)) {
  861. const find = state.selectRowData.find((row: any) => {
  862. return row.id === next.id
  863. })
  864. if (!find) {
  865. state.selectRowData.push({
  866. ...next,
  867. paymentType: [] as any,
  868. musicPriceDisable: false // 默认可以编辑曲目价格
  869. })
  870. }
  871. }
  872. })
  873. // 去掉行更新值
  874. state.selectRowData = state.selectRowData.filter((next: any) => {
  875. return checkedRowKeysRef.value.includes(next.id)
  876. })
  877. }
  878. return () => {
  879. return (
  880. <div class="system-menu-container">
  881. <NSpace vertical size="medium">
  882. <NSteps
  883. current={state.currentStep}
  884. // onUpdateCurrent={()=>{
  885. // state.currentStep = val
  886. // }}
  887. style={'margin-bottom: 10px;margin-top: 10px'}
  888. >
  889. <NStep title="选择曲目" description=""></NStep>
  890. <NStep title="设置曲目信息" description=""></NStep>
  891. </NSteps>
  892. </NSpace>
  893. {state.currentStep === 1 && (
  894. <div class="system-menu-container">
  895. <SaveForm
  896. ref={saveForm}
  897. model={state.searchForm}
  898. onSubmit={onSubmit}
  899. // saveKey="cooleshow-edu-addMusic"
  900. onSetModel={(val: any) => (state.searchForm = val)}
  901. >
  902. <NFormItem label="关键词" path="keyword">
  903. <NInput
  904. v-model:value={state.searchForm.keyword}
  905. placeholder="请输入曲目名称/编号"
  906. clearable
  907. />
  908. </NFormItem>
  909. <NFormItem label="曲目类型" path="musicSheetType">
  910. <NSelect
  911. placeholder="请选择曲目类型"
  912. v-model:value={state.searchForm.musicSheetType}
  913. options={getSelectDataFromObj(musicSheetType)}
  914. clearable
  915. />
  916. </NFormItem>
  917. <NFormItem label="声部" path="musicSubject">
  918. <NSelect
  919. placeholder="请选择声部"
  920. v-model:value={state.searchForm.subjectId}
  921. options={state.subjectList}
  922. clearable
  923. />
  924. </NFormItem>
  925. <NFormItem label="曲目来源" path="sourceType">
  926. <NSelect
  927. placeholder="请选择曲目来源"
  928. v-model:value={state.searchForm.sourceType}
  929. options={getSelectDataFromObj(musicSheetSourceType)}
  930. // onUpdateValue={async (value: any) => {
  931. // }}
  932. clearable
  933. />
  934. </NFormItem>
  935. <NFormItem>
  936. <NSpace>
  937. <NButton type="primary" onClick={onSearch}>
  938. 搜索
  939. </NButton>
  940. <NButton type="default" onClick={onBtnReset}>
  941. 重置
  942. </NButton>
  943. </NSpace>
  944. </NFormItem>
  945. </SaveForm>
  946. <p style={{ paddingBottom: '12px' }}>
  947. 你选择了<span style={'color:red;padding:0 8px'}>{state.selectRowData.length}</span>
  948. 条曲目
  949. </p>
  950. <NDataTable
  951. loading={state.loading}
  952. columns={columns()}
  953. data={state.dataList}
  954. rowKey={(row: any) => row.id}
  955. onUpdateCheckedRowKeys={handleCheck}
  956. ></NDataTable>
  957. <Pagination
  958. v-model:page={state.pagination.page}
  959. v-model:pageSize={state.pagination.rows}
  960. v-model:pageTotal={state.pagination.pageTotal}
  961. onList={getList}
  962. sync
  963. // saveKey="cooleshow-edu-addMusic"
  964. ></Pagination>
  965. </div>
  966. )}
  967. {state.currentStep === 2 && (
  968. <div class="system-menu-container" style={'margin-top: 15px;'}>
  969. <NDataTable
  970. loading={state.loading}
  971. columns={stepColumns()}
  972. data={state.selectRowData}
  973. rowKey={(row: any) => row.id}
  974. maxHeight={500}
  975. scrollX={2000}
  976. ></NDataTable>
  977. </div>
  978. )}
  979. <NSpace justify="end" style={'margin-top:10px'}>
  980. <NButton
  981. type="default"
  982. onClick={() => {
  983. if (state.currentStep > 1) {
  984. state.currentStep = state.currentStep - 1
  985. } else {
  986. emit('close')
  987. }
  988. }}
  989. >
  990. {state.currentStep === 1 ? '取消' : '上一步'}
  991. </NButton>
  992. <NButton
  993. type="primary"
  994. onClick={() => {
  995. if (state.currentStep < 2) {
  996. if (state.selectRowData.length == 0) {
  997. message.warning('请选择曲目')
  998. return
  999. }
  1000. state.currentStep = state.currentStep + 1
  1001. } else {
  1002. onSave()
  1003. }
  1004. }}
  1005. // loading={btnLoading.value}
  1006. // disabled={btnLoading.value}
  1007. >
  1008. {state.currentStep === 2 ? '确定' : '下一步'}
  1009. </NButton>
  1010. </NSpace>
  1011. </div>
  1012. )
  1013. }
  1014. }
  1015. })