addMusic.tsx 38 KB

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