addMusic.tsx 31 KB

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