addMusic.tsx 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  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 === 'FREE') {
  146. item.musicPrice = 0
  147. } else {
  148. if (!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) {
  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. },
  204. {
  205. title: '曲目名称',
  206. key: 'name'
  207. },
  208. {
  209. title: '音乐人',
  210. key: 'composer'
  211. },
  212. {
  213. title: '曲目类型',
  214. key: 'musicSheetType',
  215. render: (row: any) => {
  216. return (
  217. <div>
  218. {getMapValueByKey(row.musicSheetType, new Map(Object.entries(musicSheetType)))}
  219. </div>
  220. )
  221. }
  222. },
  223. {
  224. title: '作者属性',
  225. key: 'sourceType',
  226. render(row: any) {
  227. return getMapValueByKey(row.sourceType, new Map(Object.entries(musicSheetSourceType)))
  228. }
  229. },
  230. {
  231. title: '所属人',
  232. key: 'userName',
  233. render: (row: any) => {
  234. return <TheTooltip content={getOwnerName(row.musicSheetExtend, row.sourceType)} />
  235. }
  236. }
  237. ]
  238. const columns = (): any => {
  239. return columnsField
  240. }
  241. const stepColumns = (): DataTableColumns => {
  242. const field = deepClone(columnsField)
  243. field.splice(0, 1)
  244. field.push({
  245. title(column: any) {
  246. return (
  247. <NSpace>
  248. 曲目标签
  249. <NButton
  250. type="primary"
  251. size="small"
  252. text
  253. onClick={() => {
  254. dialogs.create({
  255. title: '请选择曲目标签',
  256. showIcon: false,
  257. content: () => {
  258. return h(
  259. 'div',
  260. {
  261. class: 'flex flex-col justify-center items-center text-14px'
  262. },
  263. [
  264. h(NSelect, {
  265. onUpdateValue(v) {
  266. state.globalMusicTagIds = v
  267. },
  268. multiple: true,
  269. clearable: true,
  270. options: state.musicSheetTagList
  271. })
  272. ]
  273. )
  274. },
  275. positiveText: '确定',
  276. negativeText: '取消',
  277. onPositiveClick: () => {
  278. for (let i = 0; i < state.selectRowData.length; i++) {
  279. const item = state.selectRowData[i]
  280. item.musicTagIds = state.globalMusicTagIds
  281. }
  282. }
  283. })
  284. }}
  285. >
  286. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  287. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  288. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  289. <path
  290. 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"
  291. fill="currentColor"
  292. ></path>
  293. </svg>
  294. </NIcon>
  295. </NButton>
  296. </NSpace>
  297. )
  298. },
  299. key: 'musicTagIds',
  300. render: (row: any) => {
  301. // })
  302. return (
  303. <NSelect
  304. placeholder="请选择曲目标签"
  305. value={row.musicTagIds}
  306. options={state.musicSheetTagList}
  307. clearable
  308. multiple
  309. maxTagCount={1}
  310. onUpdateValue={(value) => {
  311. row['musicTagIds'] = value
  312. }}
  313. />
  314. )
  315. }
  316. })
  317. field.push({
  318. title(column: any) {
  319. return (
  320. <NSpace>
  321. 收费方式
  322. <NButton
  323. type="primary"
  324. size="small"
  325. text
  326. onClick={() => {
  327. dialogs.create({
  328. title: '请选择收费方式',
  329. showIcon: false,
  330. content: () => {
  331. return h(
  332. 'div',
  333. {
  334. class: 'flex flex-col justify-center items-center text-14px'
  335. },
  336. [
  337. h(NSelect, {
  338. value: state.globalPaymentType,
  339. onUpdateValue(v) {
  340. state.globalPaymentType = v
  341. const free = 'FREE'
  342. if (state.globalPaymentType[state.globalPaymentType.length - 1] == free) {
  343. state.globalPaymentType = [free]
  344. return
  345. }
  346. if (state.globalPaymentType.length > 1 && state.globalPaymentType.includes(free)) {
  347. state.globalPaymentType.splice(state.globalPaymentType.indexOf(free), 1)
  348. }
  349. },
  350. multiple: true,
  351. clearable: true,
  352. options: getSelectDataFromObj(musicSheetPaymentType)
  353. }
  354. )
  355. ]
  356. )
  357. },
  358. positiveText: '确定',
  359. negativeText: '取消',
  360. onPositiveClick: () => {
  361. for (let i = 0; i < state.selectRowData.length; i++) {
  362. const item = state.selectRowData[i]
  363. item.paymentType = state.globalPaymentType
  364. }
  365. }
  366. })
  367. }}
  368. >
  369. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  370. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  371. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  372. <path
  373. 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"
  374. fill="currentColor"
  375. ></path>
  376. </svg>
  377. </NIcon>
  378. </NButton>
  379. </NSpace>
  380. )
  381. },
  382. key: 'paymentType',
  383. width:'180px',
  384. render: (row: any) => {
  385. return (
  386. <NSelect
  387. placeholder="请选择收费方式"
  388. value={row.paymentType as []}
  389. options={getSelectDataFromObj(musicSheetPaymentType)}
  390. clearable
  391. multiple
  392. onUpdate:value={(value) => {
  393. row.paymentType = value
  394. const free = 'FREE'
  395. if(row.paymentType[row.paymentType.length - 1] == free) {
  396. row.paymentType = [free]
  397. return
  398. }
  399. if (row.paymentType.length > 1 && row.paymentType.includes(free)) {
  400. row.paymentType.splice(row.paymentType.indexOf(free), 1)
  401. }
  402. }}
  403. />
  404. )
  405. }
  406. })
  407. field.push({
  408. title(column: any) {
  409. return (
  410. <NSpace>
  411. 曲目价格
  412. <NButton
  413. type="primary"
  414. size="small"
  415. text
  416. onClick={() => {
  417. dialogs.create({
  418. title: '请输入曲目价格',
  419. showIcon: false,
  420. content: () => {
  421. return h(
  422. 'div',
  423. {
  424. class: 'flex flex-col justify-center items-center text-14px'
  425. },
  426. [
  427. // icon
  428. h(NInputNumber, {
  429. onUpdateValue(v) {
  430. state.globalMusicPrice = v
  431. },
  432. min: 0,
  433. max: 9999
  434. })
  435. ]
  436. )
  437. },
  438. positiveText: '确定',
  439. negativeText: '取消',
  440. onPositiveClick: () => {
  441. if (state.globalMusicPrice) {
  442. for (let i = 0; i < state.selectRowData.length; i++) {
  443. const item = state.selectRowData[i]
  444. item.musicPrice = state.globalMusicPrice
  445. }
  446. }
  447. }
  448. })
  449. }}
  450. >
  451. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  452. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  453. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  454. <path
  455. 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"
  456. fill="currentColor"
  457. ></path>
  458. </svg>
  459. </NIcon>
  460. </NButton>
  461. </NSpace>
  462. )
  463. },
  464. key: 'musicPrice',
  465. render: (row: any) => {
  466. return h(NInputNumber, {
  467. value: row.musicPrice,
  468. min: 0,
  469. max: 9999,
  470. onUpdateValue(value: any) {
  471. row['musicPrice'] = value
  472. }
  473. })
  474. }
  475. })
  476. field.push({
  477. title(column: any) {
  478. return (
  479. <NSpace>
  480. 可用途径
  481. <NButton
  482. type="primary"
  483. size="small"
  484. text
  485. onClick={() => {
  486. dialogs.create({
  487. title: '请选择可用途径',
  488. showIcon: false,
  489. content: () => {
  490. return h(
  491. 'div',
  492. {
  493. class: 'flex flex-col justify-center items-center text-14px'
  494. },
  495. [
  496. // icon
  497. h(NSelect, {
  498. onUpdateValue(v) {
  499. state.globalAvailableType = v
  500. },
  501. clearable: true,
  502. options: getSelectDataFromObj(musicSheetAvailableType)
  503. })
  504. ]
  505. )
  506. },
  507. positiveText: '确定',
  508. negativeText: '取消',
  509. onPositiveClick: () => {
  510. for (let i = 0; i < state.selectRowData.length; i++) {
  511. const item = state.selectRowData[i]
  512. item.availableType = state.globalAvailableType
  513. }
  514. }
  515. })
  516. }}
  517. >
  518. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  519. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  520. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  521. <path
  522. 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"
  523. fill="currentColor"
  524. ></path>
  525. </svg>
  526. </NIcon>
  527. </NButton>
  528. </NSpace>
  529. )
  530. },
  531. key: 'availableType',
  532. render: (row: any) => {
  533. return (
  534. <NSelect
  535. placeholder="请选择可用途径"
  536. value={row.availableType}
  537. options={getSelectDataFromObj(musicSheetAvailableType)}
  538. onUpdateValue={(value) => {
  539. row['availableType'] = value
  540. }}
  541. clearable
  542. />
  543. )
  544. }
  545. })
  546. field.push({
  547. title(column: any) {
  548. return (
  549. <NSpace>
  550. 是否置顶
  551. <NButton
  552. type="primary"
  553. size="small"
  554. text
  555. onClick={() => {
  556. dialogs.create({
  557. title: '请选择是否置顶',
  558. showIcon: false,
  559. content: () => {
  560. return h(
  561. 'div',
  562. {
  563. class: 'flex flex-col justify-center items-center text-14px'
  564. },
  565. [
  566. // icon
  567. h(NSelect, {
  568. onUpdateValue(v) {
  569. state.globalTopFlag = v
  570. },
  571. options: [
  572. {
  573. label: '是',
  574. value: true
  575. },
  576. {
  577. label: '否',
  578. value: false
  579. }
  580. ] as any
  581. })
  582. ]
  583. )
  584. },
  585. positiveText: '确定',
  586. negativeText: '取消',
  587. onPositiveClick: () => {
  588. for (let i = 0; i < state.selectRowData.length; i++) {
  589. const item = state.selectRowData[i]
  590. item.topFlag = state.globalTopFlag
  591. }
  592. }
  593. })
  594. }}
  595. >
  596. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  597. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  598. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  599. <path
  600. 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"
  601. fill="currentColor"
  602. ></path>
  603. </svg>
  604. </NIcon>
  605. </NButton>
  606. </NSpace>
  607. )
  608. },
  609. key: 'topFlag',
  610. render: (row: any) => {
  611. return (
  612. <NSelect
  613. placeholder="请选择是否置顶"
  614. value={row.topFlag}
  615. options={
  616. [
  617. {
  618. label: '是',
  619. value: true
  620. },
  621. {
  622. label: '否',
  623. value: false
  624. }
  625. ] as any
  626. }
  627. clearable
  628. onUpdateValue={(value) => {
  629. row['topFlag'] = value
  630. }}
  631. />
  632. )
  633. }
  634. })
  635. field.push({
  636. title(column: any) {
  637. return (
  638. <NSpace>
  639. 是否精品
  640. <NButton
  641. type="primary"
  642. size="small"
  643. text
  644. onClick={() => {
  645. dialogs.create({
  646. title: '请选择是否精品',
  647. showIcon: false,
  648. content: () => {
  649. return h(
  650. 'div',
  651. {
  652. class: 'flex flex-col justify-center items-center text-14px'
  653. },
  654. [
  655. // icon
  656. h(NSelect, {
  657. onUpdateValue(v) {
  658. state.globalExquisiteFlag = v
  659. },
  660. options: [
  661. {
  662. label: '是',
  663. value: true
  664. },
  665. {
  666. label: '否',
  667. value: false
  668. }
  669. ] as any
  670. })
  671. ]
  672. )
  673. },
  674. positiveText: '确定',
  675. negativeText: '取消',
  676. onPositiveClick: () => {
  677. for (let i = 0; i < state.selectRowData.length; i++) {
  678. const item = state.selectRowData[i]
  679. item.exquisiteFlag = state.globalExquisiteFlag
  680. }
  681. }
  682. })
  683. }}
  684. >
  685. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  686. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  687. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  688. <path
  689. 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"
  690. fill="currentColor"
  691. ></path>
  692. </svg>
  693. </NIcon>
  694. </NButton>
  695. </NSpace>
  696. )
  697. },
  698. key: 'exquisiteFlag',
  699. render: (row: any) => {
  700. return (
  701. <NSelect
  702. placeholder="请选择是否精品"
  703. value={row.exquisiteFlag}
  704. onUpdateValue={(value) => {
  705. row['exquisiteFlag'] = value
  706. }}
  707. options={
  708. [
  709. {
  710. label: '是',
  711. value: true
  712. },
  713. {
  714. label: '否',
  715. value: false
  716. }
  717. ] as any
  718. }
  719. clearable
  720. />
  721. )
  722. }
  723. })
  724. field.push({
  725. title(column: any) {
  726. return (
  727. <NSpace>
  728. 排序
  729. <NButton
  730. type="primary"
  731. size="small"
  732. text
  733. onClick={() => {
  734. dialogs.create({
  735. title: '请输入排序起始值',
  736. showIcon: false,
  737. content: () => {
  738. return h(
  739. 'div',
  740. {
  741. class: 'flex flex-col justify-center items-center text-14px'
  742. },
  743. [
  744. // icon
  745. h(NInputNumber, {
  746. onUpdateValue(v) {
  747. state.globalStartSortNum = v
  748. },
  749. min: 0,
  750. max: 9999
  751. })
  752. ]
  753. )
  754. },
  755. positiveText: '确定',
  756. negativeText: '取消',
  757. onPositiveClick: () => {
  758. for (let i = 0; i < state.selectRowData.length; i++) {
  759. const item = state.selectRowData[i]
  760. item.sortNo = state.globalStartSortNum + i
  761. }
  762. }
  763. })
  764. }}
  765. >
  766. <NIcon size={15} style="padding-left: 5px;margin-top:4px">
  767. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  768. <path d="M2 26h28v2H2z" fill="currentColor"></path>
  769. <path
  770. 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"
  771. fill="currentColor"
  772. ></path>
  773. </svg>
  774. </NIcon>
  775. </NButton>
  776. </NSpace>
  777. )
  778. },
  779. key: 'sortNo',
  780. fixed: 'right',
  781. width: 150,
  782. render: (row: any) => {
  783. return h(NInputNumber, {
  784. value: row.sortNo,
  785. min: 0,
  786. max: 9999,
  787. onUpdateValue(value: any) {
  788. row.sortNo = value
  789. }
  790. })
  791. }
  792. })
  793. field.push({
  794. title: '操作',
  795. key: 'operation',
  796. fixed: 'right',
  797. render(row: any) {
  798. return (
  799. <NSpace>
  800. <NButton
  801. type="primary"
  802. size="small"
  803. text
  804. //v-auth="musicSheet/update1602302618558099458"
  805. onClick={() => {
  806. dialogs.warning({
  807. title: '警告',
  808. content: `是否删除该数据?`,
  809. positiveText: '确定',
  810. negativeText: '取消',
  811. onPositiveClick: async () => {
  812. try {
  813. const index = state.selectRowData.findIndex((item: any) => {
  814. if (item.id == row.id) {
  815. return true
  816. }
  817. })
  818. if (index > -1) {
  819. state.selectRowData.splice(index, 1)
  820. }
  821. const index1 = checkedRowKeysRef.value.findIndex((item: any) => {
  822. if (item == row.id) {
  823. return true
  824. }
  825. })
  826. if (index1 > -1) {
  827. checkedRowKeysRef.value.splice(index, 1)
  828. }
  829. } catch {}
  830. }
  831. })
  832. }}
  833. >
  834. 移除
  835. </NButton>
  836. </NSpace>
  837. )
  838. }
  839. })
  840. return field
  841. }
  842. const checkedRowKeysRef = ref<DataTableRowKey[]>([])
  843. const handleCheck = (rowKeys: DataTableRowKey[]) => {
  844. checkedRowKeysRef.value = rowKeys
  845. // 添加行更新值
  846. state.dataList.forEach((next: any) => {
  847. if (checkedRowKeysRef.value.includes(next.id)) {
  848. const find = state.selectRowData.find((row: any) => {
  849. return row.id === next.id
  850. })
  851. if (!find) {
  852. state.selectRowData.push(next)
  853. }
  854. }
  855. })
  856. // 去掉行更新值
  857. state.selectRowData = state.selectRowData.filter((next: any) => {
  858. return checkedRowKeysRef.value.includes(next.id)
  859. })
  860. }
  861. return () => {
  862. return (
  863. <div class="system-menu-container">
  864. <NSpace vertical size="medium">
  865. <NSteps
  866. current={state.currentStep}
  867. // onUpdateCurrent={()=>{
  868. // state.currentStep = val
  869. // }}
  870. style={'margin-bottom: 10px;margin-top: 10px'}
  871. >
  872. <NStep title="选择曲目" description=""></NStep>
  873. <NStep title="设置曲目信息" description=""></NStep>
  874. </NSteps>
  875. </NSpace>
  876. {state.currentStep === 1 && (
  877. <div class="system-menu-container">
  878. <SaveForm
  879. ref={saveForm}
  880. model={state.searchForm}
  881. onSubmit={onSubmit}
  882. // saveKey="cooleshow-edu-addMusic"
  883. onSetModel={(val: any) => (state.searchForm = val)}
  884. >
  885. <NFormItem label="关键词" path="keyword">
  886. <NInput
  887. v-model:value={state.searchForm.keyword}
  888. placeholder="请输入曲目名称/编号"
  889. clearable
  890. />
  891. </NFormItem>
  892. <NFormItem label="曲目类型" path="musicSheetType">
  893. <NSelect
  894. placeholder="请选择曲目类型"
  895. v-model:value={state.searchForm.musicSheetType}
  896. options={getSelectDataFromObj(musicSheetType)}
  897. clearable
  898. />
  899. </NFormItem>
  900. <NFormItem label="声部" path="musicSubject">
  901. <NSelect
  902. placeholder="请选择声部"
  903. v-model:value={state.searchForm.subjectId}
  904. options={state.subjectList}
  905. clearable
  906. />
  907. </NFormItem>
  908. <NFormItem label="曲目来源" path="sourceType">
  909. <NSelect
  910. placeholder="请选择曲目来源"
  911. v-model:value={state.searchForm.sourceType}
  912. options={getSelectDataFromObj(musicSheetSourceType)}
  913. // onUpdateValue={async (value: any) => {
  914. // }}
  915. clearable
  916. />
  917. </NFormItem>
  918. <NFormItem>
  919. <NSpace>
  920. <NButton type="primary" onClick={onSearch}>
  921. 搜索
  922. </NButton>
  923. <NButton type="default" onClick={onBtnReset}>
  924. 重置
  925. </NButton>
  926. </NSpace>
  927. </NFormItem>
  928. </SaveForm>
  929. <p style={{ paddingBottom: '12px' }}>
  930. 你选择了<span style={'color:red;padding:0 8px'}>{state.selectRowData.length}</span>
  931. 条曲目
  932. </p>
  933. <NDataTable
  934. loading={state.loading}
  935. columns={columns()}
  936. data={state.dataList}
  937. rowKey={(row: any) => row.id}
  938. onUpdateCheckedRowKeys={handleCheck}
  939. ></NDataTable>
  940. <Pagination
  941. v-model:page={state.pagination.page}
  942. v-model:pageSize={state.pagination.rows}
  943. v-model:pageTotal={state.pagination.pageTotal}
  944. onList={getList}
  945. sync
  946. // saveKey="cooleshow-edu-addMusic"
  947. ></Pagination>
  948. </div>
  949. )}
  950. {state.currentStep === 2 && (
  951. <div class="system-menu-container" style={'margin-top: 15px;'}>
  952. <NDataTable
  953. loading={state.loading}
  954. columns={stepColumns()}
  955. data={state.selectRowData}
  956. rowKey={(row: any) => row.id}
  957. maxHeight={500}
  958. scrollX={2000}
  959. ></NDataTable>
  960. </div>
  961. )}
  962. <NSpace justify="end" style={'margin-top:10px'}>
  963. <NButton
  964. type="default"
  965. onClick={() => {
  966. if (state.currentStep > 1) {
  967. state.currentStep = state.currentStep - 1
  968. } else {
  969. emit('close')
  970. }
  971. }}
  972. >
  973. {state.currentStep === 1 ? '取消' : '上一步'}
  974. </NButton>
  975. <NButton
  976. type="primary"
  977. onClick={() => {
  978. if (state.currentStep < 2) {
  979. if (state.selectRowData.length == 0) {
  980. message.warning('请选择曲目')
  981. return
  982. }
  983. state.currentStep = state.currentStep + 1
  984. } else {
  985. onSave()
  986. }
  987. }}
  988. // loading={btnLoading.value}
  989. // disabled={btnLoading.value}
  990. >
  991. {state.currentStep === 2 ? '确定' : '下一步'}
  992. </NButton>
  993. </NSpace>
  994. </div>
  995. )
  996. }
  997. }
  998. })