music-platform.tsx 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. import { appKey, musicSheetAvailableType, musicSheetPaymentType, musicSheetSourceType, musicSheetType, scoreType } from '@/utils/constant'
  2. import { getSelectDataFromObj } from '@/utils/objectUtil'
  3. import { NButton, NCheckbox, NForm, NFormItem, NGi, NGrid, NInputNumber, NSelect, NSpace, NSpin, useMessage } from 'naive-ui'
  4. import {computed, defineComponent, onMounted, reactive, ref} from 'vue'
  5. import { musicSheetApplicationExtendCategoryList, musicSheetApplicationExtendTagList, musicSheetApplicationExtendCategoryApplicationExtendInfo, musicSheetApplicationExtendSave } from '../../api'
  6. import { Console } from 'console'
  7. export default defineComponent({
  8. name: 'music-platform',
  9. props: {
  10. type: {
  11. type: String,
  12. default: ''
  13. },
  14. useProject: {
  15. type: Array,
  16. required: true,
  17. default: []
  18. },
  19. id: {
  20. type: String,
  21. required: true,
  22. default: null
  23. }
  24. },
  25. emits: ['close', 'getList'],
  26. setup(props, { emit }) {
  27. // 'KT' | 'GYT' | 'KLX' | 'GYM' | 'KLXT'
  28. const message = useMessage()
  29. const forms = reactive({
  30. gym: {
  31. applicationId: '',
  32. checked: true,
  33. paymentType: 'VIP',
  34. isConvertibleScore: false,
  35. scoreType: 'STAVE',
  36. status: false,
  37. sortNo: null
  38. },
  39. gyt: {
  40. applicationId: '',
  41. checked: true,
  42. availableType: 'PLATFORM',
  43. isConvertibleScore: false,
  44. scoreType: 'STAVE',
  45. status: false,
  46. sortNo: null
  47. },
  48. klxt: {
  49. applicationId: '',
  50. checked: true,
  51. isConvertibleScore: false,
  52. scoreType: 'STAVE',
  53. status: false,
  54. sortNo: null
  55. },
  56. klx: {
  57. applicationId: '',
  58. checked: true,
  59. musicTagIds: [] as any, // 标签
  60. paymentType: ['VIP'] as any, // 收费方式
  61. musicPrice: null as any, // 曲目价格
  62. availableType: 'PLATFORM',
  63. topFlag: false,
  64. exquisiteFlag: false,
  65. isConvertibleScore: true,
  66. scoreType: 'FIRST',
  67. status: false,
  68. sortNo: null
  69. },
  70. kt: {
  71. applicationId: '',
  72. checked: true,
  73. musicSheetCategoryId: null, // 乐谱教材
  74. paymentType: 'VIP',
  75. isConvertibleScore: true,
  76. scoreType: 'FIRST',
  77. status: false,
  78. sortNo: null
  79. }
  80. })
  81. // 类型是否支持
  82. const useProjectStatus = computed(() => {
  83. return {
  84. GYM: checkHasProject('GYM'),
  85. KLX_JG: checkHasProject("KLX_JG"),
  86. KLX: checkHasProject("KLX"),
  87. KT: checkHasProject("KT"),
  88. GYT: checkHasProject("GYT")
  89. }
  90. })
  91. const formsRef = ref()
  92. const dataLoading = ref(false)
  93. const musicSheetTagList = ref<any[]>([])
  94. const musicSheetCategories = ref<any[]>([])
  95. const btnLoading = ref(false)
  96. // 检测是否存在
  97. const checkHasProject = (name: string) => {
  98. const useProject = props.useProject || []
  99. return useProject.findIndex((item: any) => item.appKey === name) !== -1 ? true : false
  100. }
  101. /** 检测数据 */
  102. const checkSubmitForms = () => {
  103. let status = false
  104. const gym = forms.gym
  105. if(gym.checked) {
  106. if(!gym.paymentType) {
  107. message.error('请选择收费方式')
  108. return true
  109. }
  110. if(!gym.isConvertibleScore == null) {
  111. message.error('请选择是否支持转谱')
  112. return true
  113. }
  114. if(!gym.scoreType) {
  115. message.error('请选择默认谱面')
  116. return true
  117. }
  118. if(gym.status == null) {
  119. message.error('请选择是否启用')
  120. return true
  121. }
  122. }
  123. const gyt = forms.gyt
  124. if(gyt.checked) {
  125. if(!gyt.availableType) {
  126. message.error('请选择可用途径')
  127. return true
  128. }
  129. if(!gyt.isConvertibleScore == null) {
  130. message.error('请选择是否支持转谱')
  131. return true
  132. }
  133. if(!gyt.scoreType) {
  134. message.error('请选择默认谱面')
  135. return true
  136. }
  137. if(gyt.status == null) {
  138. message.error('请选择是否启用')
  139. return true
  140. }
  141. }
  142. const klxt = forms.klxt
  143. if(klxt.checked) {
  144. if(!klxt.isConvertibleScore == null) {
  145. message.error('请选择是否支持转谱')
  146. return true
  147. }
  148. if(!klxt.scoreType) {
  149. message.error('请选择默认谱面')
  150. return true
  151. }
  152. if(klxt.status == null) {
  153. message.error('请选择是否启用')
  154. return true
  155. }
  156. }
  157. const klx = forms.klx
  158. if(klx.checked) {
  159. if(klx.musicTagIds.length <= 0) {
  160. message.error('请选择曲目标签')
  161. return true
  162. }
  163. if(!klx.paymentType) {
  164. message.error('请选择收费方式')
  165. return true
  166. }
  167. if (!klx.paymentType.includes('CHARGE')) {
  168. klx.musicPrice = 0
  169. } else {
  170. if (klx.musicPrice === null || klx.musicPrice === undefined || klx.musicPrice === '') {
  171. message.error('曲目价格不能为空')
  172. return true
  173. }
  174. }
  175. if(!klx.availableType == null) {
  176. message.error('请选择可用途径')
  177. return true
  178. }
  179. if (typeof klx.topFlag !== 'boolean') {
  180. message.error('请选择是否置顶')
  181. return
  182. }
  183. if (typeof klx.exquisiteFlag !== 'boolean') {
  184. message.error('请选择是否精品')
  185. return
  186. }
  187. if(klx.isConvertibleScore == null) {
  188. message.error('请选择是否支持转谱')
  189. return true
  190. }
  191. if(!klx.scoreType) {
  192. message.error('请选择默认谱面')
  193. return true
  194. }
  195. if(klx.status == null) {
  196. message.error('请选择是否启用')
  197. return true
  198. }
  199. }
  200. const kt = forms.kt
  201. if(kt.checked) {
  202. if(!kt.musicSheetCategoryId) {
  203. message.error('请选择乐谱教材')
  204. return true
  205. }
  206. if(!kt.paymentType) {
  207. message.error('请选择收费方式')
  208. return true
  209. }
  210. if(!kt.isConvertibleScore == null) {
  211. message.error('请选择是否支持转谱')
  212. return true
  213. }
  214. if(!kt.scoreType) {
  215. message.error('请选择默认谱面')
  216. return true
  217. }
  218. if(kt.status == null) {
  219. message.error('请选择是否启用')
  220. return true
  221. }
  222. }
  223. return status
  224. }
  225. /** 获取参数 */
  226. const getSubmitParams = () => {
  227. const params: any = []
  228. const useApplicationIds: any = []
  229. if(forms.gym.checked) {
  230. params.push({
  231. ...forms.gym
  232. })
  233. useApplicationIds.push(forms.gym.applicationId)
  234. }
  235. if(forms.gyt.checked) {
  236. params.push({
  237. ...forms.gyt
  238. })
  239. useApplicationIds.push(forms.gyt.applicationId)
  240. }
  241. if(forms.klxt.checked) {
  242. params.push({
  243. ...forms.klxt
  244. })
  245. useApplicationIds.push(forms.klxt.applicationId)
  246. }
  247. if(forms.klx.checked) {
  248. params.push({
  249. ...forms.klx,
  250. musicTagIds: forms.klx.musicTagIds.join(','),
  251. paymentType: forms.klx.paymentType.join(',')
  252. })
  253. useApplicationIds.push(forms.klx.applicationId)
  254. }
  255. if(forms.kt.checked) {
  256. params.push({
  257. ...forms.kt
  258. })
  259. useApplicationIds.push(forms.kt.applicationId)
  260. }
  261. return {
  262. musicSheetId: props.id,
  263. applicationExtends: params || {},
  264. useApplicationIds: useApplicationIds.join(',') || ''
  265. }
  266. }
  267. // 提交数据
  268. const onSubmit = async () => {
  269. try {
  270. if(checkSubmitForms()) return
  271. const params = getSubmitParams()
  272. await musicSheetApplicationExtendSave(params)
  273. message.success('保存成功')
  274. emit('close')
  275. emit('getList')
  276. } catch {}
  277. }
  278. /** 酷乐秀 加载曲目标签 */
  279. const getMusicTags = async () => {
  280. try {
  281. const useProject = props.useProject || []
  282. const item: any = useProject.find((item: any) => item.appKey === 'KLX')
  283. if(!item) return
  284. const { data } = await musicSheetApplicationExtendTagList({
  285. applicationId: item.id
  286. })
  287. if (data && data.length > 0) {
  288. data.forEach((item: any) => {
  289. musicSheetTagList.value.push({
  290. ...item,
  291. label: item.name,
  292. value: item.id
  293. })
  294. })
  295. }
  296. } catch (err) {}
  297. }
  298. /** 课堂乐器 乐谱教材 */
  299. const getMusicSheetCategories = async () => {
  300. //加载曲目分类列表
  301. const useProject = props.useProject || []
  302. const item: any = useProject.find((item: any) => item.appKey === 'KT')
  303. if(!item) return
  304. const categoryRes = await musicSheetApplicationExtendCategoryList({
  305. applicationIds: item.id
  306. })
  307. if (categoryRes.data && categoryRes.data.length > 0) {
  308. musicSheetCategories.value = categoryRes.data[0].musicSheetCategories
  309. }
  310. }
  311. const getDetail = async () => {
  312. try {
  313. // 加载已经配置的APP
  314. const { data } = await musicSheetApplicationExtendCategoryApplicationExtendInfo({ musicSheetId: props.id })
  315. const result = data || []
  316. result.forEach((item: any) => {
  317. if(item.appKey === 'GYM') {
  318. forms.gym.checked = true;
  319. forms.gym.paymentType = item.paymentType
  320. forms.gym.isConvertibleScore = item.isConvertibleScore
  321. forms.gym.scoreType = item.scoreType
  322. forms.gym.status = item.status
  323. forms.gym.sortNo = item.sortNo
  324. } else if(item.appKey === 'GYT') {
  325. forms.gyt.checked = true
  326. forms.gyt.availableType = item.availableType
  327. forms.gyt.isConvertibleScore = item.isConvertibleScore
  328. forms.gyt.scoreType = item.scoreType
  329. forms.gyt.status = item.status
  330. forms.gyt.sortNo = item.sortNo
  331. } else if(item.appKey === 'KLX_JG') {
  332. forms.klxt.checked = true
  333. forms.klxt.isConvertibleScore = false
  334. forms.klxt.scoreType = 'STAVE'
  335. forms.klxt.status = false
  336. forms.klxt.sortNo = null
  337. } else if(item.appKey === 'KLX') {
  338. forms.klx.checked = true
  339. forms.klx.musicTagIds = item.musicTagIds ? item.musicTagIds.split(',') : [] // 标签
  340. forms.klx.paymentType = item.paymentType ? item.paymentType.split(',') : [] // 收费方式
  341. forms.klx.musicPrice = item.musicPrice // 曲目价格
  342. forms.klx.availableType = item.availableType
  343. forms.klx.topFlag = item.topFlag
  344. forms.klx.exquisiteFlag = item.exquisiteFlag
  345. forms.klx.isConvertibleScore = item.isConvertibleScore
  346. forms.klx.scoreType = item.scoreType
  347. forms.klx.status = item.status
  348. forms.klx.sortNo = item.sortNo
  349. } else if(item.appKey === 'KT') {
  350. forms.kt.checked = true
  351. forms.kt.musicSheetCategoryId = item.musicSheetCategoryId // 乐谱教材
  352. forms.kt.paymentType = item.paymentType
  353. forms.kt.isConvertibleScore = item.isConvertibleScore
  354. forms.kt.scoreType = item.scoreType
  355. forms.kt.status = item.status
  356. forms.kt.sortNo = item.sortNo
  357. }
  358. })
  359. } catch {
  360. }
  361. }
  362. onMounted(async () => {
  363. dataLoading.value = true
  364. if(props.type !== 'add') {
  365. // 默认重置为false
  366. forms.gym.checked = false
  367. forms.gyt.checked = false
  368. forms.klxt.checked = false
  369. forms.klx.checked = false
  370. forms.kt.checked = false
  371. }
  372. // 初始话应用编号
  373. const useProject = props.useProject || []
  374. useProject.forEach((item: any) => {
  375. if(item.appKey === 'GYM') {
  376. forms.gym.applicationId = item.id
  377. } else if(item.appKey === 'KLX_JG') {
  378. forms.klxt.applicationId = item.id
  379. } else if(item.appKey === 'KLX') {
  380. forms.klx.applicationId = item.id
  381. } else if(item.appKey === 'KT') {
  382. forms.kt.applicationId = item.id
  383. } else if(item.appKey === 'GYT') {
  384. forms.gyt.applicationId = item.id
  385. }
  386. })
  387. await getMusicTags()
  388. await getMusicSheetCategories()
  389. await getDetail()
  390. dataLoading.value = false
  391. })
  392. return () => <NSpin show={dataLoading.value}>
  393. <NForm
  394. model={forms}
  395. ref={formsRef}
  396. label-placement="top"
  397. label-width="85"
  398. >
  399. {useProjectStatus.value.GYM && <NGrid cols={8} xGap={12} style={{ marginBottom: '12px' }}>
  400. <NGi span={1} style={{ display: 'flex', alignItems: 'center' }}>
  401. <NCheckbox v-model:checked={forms.gym.checked}>管乐迷</NCheckbox>
  402. </NGi>
  403. <NGi span={7} style={{ background: '#f9f9f9', padding: '20px 16px 0', borderRadius: '8px' }}>
  404. <NGrid cols={6} xGap={12}>
  405. <NGi>
  406. <NFormItem label='收费方式' path="paymentType">
  407. <NSelect v-model:value={forms.gym.paymentType} clearable options={[
  408. { label: '免费', value: 'FREE' },
  409. { label: '收费', value: 'VIP' }]} />
  410. </NFormItem>
  411. </NGi>
  412. <NGi>
  413. <NFormItem label='是否支持转谱' path="isConvertibleScore">
  414. <NSelect v-model:value={forms.gym.isConvertibleScore} clearable options={[
  415. { label: '是', value: true },
  416. { label: '否', value: false }
  417. ] as any} />
  418. </NFormItem>
  419. </NGi>
  420. <NGi>
  421. <NFormItem label='默认谱面' path="scoreType">
  422. <NSelect v-model:value={forms.gym.scoreType} options={getSelectDataFromObj(scoreType)} />
  423. </NFormItem>
  424. </NGi>
  425. <NGi>
  426. <NFormItem label='是否启用' path="status">
  427. <NSelect v-model:value={forms.gym.status} options={[
  428. { label: '是', value: true },
  429. { label: '否', value: false }
  430. ] as any} />
  431. </NFormItem>
  432. </NGi>
  433. <NGi>
  434. <NFormItem label='排序' path="sortNo">
  435. <NInputNumber min={0} max={9999} v-model:value={forms.gym.sortNo} showButton={false} />
  436. </NFormItem>
  437. </NGi>
  438. </NGrid>
  439. </NGi>
  440. </NGrid>}
  441. {useProjectStatus.value.GYT && <NGrid cols={8} xGap={12} style={{ marginBottom: '12px' }}>
  442. <NGi span={1} style={{ display: 'flex', alignItems: 'center' }}>
  443. <NCheckbox v-model:checked={forms.gyt.checked}>管乐团</NCheckbox>
  444. </NGi>
  445. <NGi span={7} style={{ background: '#f9f9f9', padding: '20px 16px 0', borderRadius: '8px' }}>
  446. <NGrid cols={6} xGap={12}>
  447. <NGi>
  448. <NFormItem label='可以途径' path="availableType">
  449. <NSelect v-model:value={forms.gyt.availableType} clearable options={[
  450. {
  451. label: '学校',
  452. value: 'ORG'
  453. },
  454. {
  455. label: '平台',
  456. value: 'PLATFORM'
  457. }
  458. ]} />
  459. </NFormItem>
  460. </NGi>
  461. <NGi>
  462. <NFormItem label='是否支持转谱' path="isConvertibleScore">
  463. <NSelect v-model:value={forms.gyt.isConvertibleScore} clearable options={[
  464. { label: '是', value: true },
  465. { label: '否', value: false }
  466. ] as any} />
  467. </NFormItem>
  468. </NGi>
  469. <NGi>
  470. <NFormItem label='默认谱面' path="scoreType">
  471. <NSelect v-model:value={forms.gyt.scoreType} options={getSelectDataFromObj(scoreType)} />
  472. </NFormItem>
  473. </NGi>
  474. <NGi>
  475. <NFormItem label='是否启用' path="status">
  476. <NSelect v-model:value={forms.gyt.status} options={[
  477. { label: '是', value: true },
  478. { label: '否', value: false }
  479. ] as any} />
  480. </NFormItem>
  481. </NGi>
  482. <NGi>
  483. <NFormItem label='排序' path="sortNo">
  484. <NInputNumber min={0} max={9999} v-model:value={forms.gyt.sortNo} showButton={false} />
  485. </NFormItem>
  486. </NGi>
  487. </NGrid>
  488. </NGi>
  489. </NGrid>}
  490. {useProjectStatus.value.KLX_JG && <NGrid cols={8} xGap={12} style={{ marginBottom: '12px' }}>
  491. <NGi span={1} style={{ display: 'flex', alignItems: 'center' }}>
  492. <NCheckbox v-model:checked={forms.klxt.checked}>酷乐秀机构</NCheckbox>
  493. </NGi>
  494. <NGi span={7} style={{ background: '#f9f9f9', padding: '20px 16px 0', borderRadius: '8px' }}>
  495. <NGrid cols={6} xGap={12}>
  496. <NGi>
  497. <NFormItem label='是否支持转谱' path="isConvertibleScore">
  498. <NSelect v-model:value={forms.klxt.isConvertibleScore} clearable options={[
  499. { label: '是', value: true },
  500. { label: '否', value: false }
  501. ] as any} />
  502. </NFormItem>
  503. </NGi>
  504. <NGi>
  505. <NFormItem label='默认谱面' path="scoreType">
  506. <NSelect v-model:value={forms.klxt.scoreType} options={getSelectDataFromObj(scoreType)} />
  507. </NFormItem>
  508. </NGi>
  509. <NGi>
  510. <NFormItem label='是否启用' path="status">
  511. <NSelect v-model:value={forms.klxt.status} options={[
  512. { label: '是', value: true },
  513. { label: '否', value: false }
  514. ] as any} />
  515. </NFormItem>
  516. </NGi>
  517. <NGi>
  518. <NFormItem label='排序' path="sortNo">
  519. <NInputNumber min={0} max={9999} v-model:value={forms.klxt.sortNo} showButton={false} />
  520. </NFormItem>
  521. </NGi>
  522. </NGrid>
  523. </NGi>
  524. </NGrid>}
  525. {useProjectStatus.value.KLX && <NGrid cols={8} xGap={12} style={{ marginBottom: '12px' }}>
  526. <NGi span={1} style={{ display: 'flex', alignItems: 'center' }}>
  527. <NCheckbox v-model:checked={forms.klx.checked}>酷乐秀平台</NCheckbox>
  528. </NGi>
  529. <NGi span={7} style={{ background: '#f9f9f9', padding: '20px 16px 0', borderRadius: '8px' }}>
  530. <NGrid cols={6} xGap={12}>
  531. <NGi>
  532. <NFormItem label='曲目标签'>
  533. <NSelect v-model:value={forms.klx.musicTagIds} multiple maxTagCount={1} clearable options={musicSheetTagList.value} />
  534. </NFormItem>
  535. </NGi>
  536. <NGi>
  537. <NFormItem label='收费方式' path="paymentType">
  538. <NSelect v-model:value={forms.klx.paymentType} multiple maxTagCount={1} clearable options={getSelectDataFromObj(musicSheetPaymentType)}
  539. onUpdate:value={(v: any) => {
  540. forms.klx.paymentType = v
  541. const free = 'FREE'
  542. if (forms.klx.paymentType[forms.klx.paymentType.length - 1] == free) {
  543. forms.klx.paymentType = [free]
  544. } else if (forms.klx.paymentType.length > 1 && forms.klx.paymentType.includes(free)) {
  545. forms.klx.paymentType.splice(forms.klx.paymentType.indexOf(free), 1)
  546. }
  547. if (!forms.klx.paymentType.includes('CHARGE')) {
  548. forms.klx.musicPrice = 0
  549. }
  550. }} />
  551. </NFormItem>
  552. </NGi>
  553. <NGi>
  554. <NFormItem label='曲目价格' path="musicPrice">
  555. <NInputNumber disabled={!forms.klx.paymentType?.includes('CHARGE')} precision={2 } min={0} max={9999} v-model:value={forms.klx.musicPrice} showButton={false} />
  556. </NFormItem>
  557. </NGi>
  558. <NGi>
  559. <NFormItem label='可用途径' path="availableType">
  560. <NSelect v-model:value={forms.klx.availableType} clearable options={getSelectDataFromObj(musicSheetAvailableType)} />
  561. </NFormItem>
  562. </NGi>
  563. <NGi>
  564. <NFormItem label='是否置顶' path="topFlag">
  565. <NSelect v-model:value={forms.klx.topFlag} clearable options={[
  566. { label: '是', value: true },
  567. { label: '否', value: false }
  568. ] as any} />
  569. </NFormItem>
  570. </NGi>
  571. <NGi>
  572. <NFormItem label='是否精品' path="exquisiteFlag">
  573. <NSelect v-model:value={forms.klx.exquisiteFlag} clearable options={[
  574. { label: '是', value: true },
  575. { label: '否', value: false }
  576. ] as any} />
  577. </NFormItem>
  578. </NGi>
  579. <NGi>
  580. <NFormItem label='是否支持转谱' path="isConvertibleScore">
  581. <NSelect v-model:value={forms.klx.isConvertibleScore} clearable options={[
  582. { label: '是', value: true },
  583. { label: '否', value: false }
  584. ] as any} />
  585. </NFormItem>
  586. </NGi>
  587. <NGi>
  588. <NFormItem label='默认谱面' path="scoreType">
  589. <NSelect v-model:value={forms.klx.scoreType} options={getSelectDataFromObj(scoreType)} />
  590. </NFormItem>
  591. </NGi>
  592. <NGi>
  593. <NFormItem label='是否启用' path="status">
  594. <NSelect v-model:value={forms.klx.status} options={[
  595. { label: '是', value: true },
  596. { label: '否', value: false }
  597. ] as any} />
  598. </NFormItem>
  599. </NGi>
  600. <NGi>
  601. <NFormItem label='排序' path="sortNo">
  602. <NInputNumber min={0} max={9999} v-model:value={forms.klx.sortNo} showButton={false} />
  603. </NFormItem>
  604. </NGi>
  605. </NGrid>
  606. </NGi>
  607. </NGrid>}
  608. {useProjectStatus.value.KT && <NGrid cols={8} xGap={12} style={{ marginBottom: '12px' }}>
  609. <NGi span={1} style={{ display: 'flex', alignItems: 'center' }}>
  610. <NCheckbox v-model:checked={forms.kt.checked}>音乐数字课堂</NCheckbox>
  611. </NGi>
  612. <NGi span={7} style={{ background: '#f9f9f9', padding: '20px 16px 0', borderRadius: '8px' }}>
  613. <NGrid cols={6} xGap={12}>
  614. <NGi>
  615. <NFormItem label='乐谱教材' path="musicSheetCategoryId">
  616. <NSelect v-model:value={forms.kt.musicSheetCategoryId} clearable options={musicSheetCategories.value} labelField='name' valueField='id' />
  617. </NFormItem>
  618. </NGi>
  619. <NGi>
  620. <NFormItem label='收费方式' path="paymentType">
  621. <NSelect v-model:value={forms.kt.paymentType} clearable options={[
  622. { label: '免费', value: 'FREE' },
  623. { label: '会员', value: 'VIP' }]} />
  624. </NFormItem>
  625. </NGi>
  626. <NGi>
  627. <NFormItem label='是否支持转谱' path="isConvertibleScore">
  628. <NSelect v-model:value={forms.kt.isConvertibleScore} clearable options={[
  629. { label: '是', value: true },
  630. { label: '否', value: false }
  631. ] as any} />
  632. </NFormItem>
  633. </NGi>
  634. <NGi>
  635. <NFormItem label='默认谱面' path="scoreType">
  636. <NSelect v-model:value={forms.kt.scoreType} options={getSelectDataFromObj(scoreType)} />
  637. </NFormItem>
  638. </NGi>
  639. <NGi>
  640. <NFormItem label='是否启用' path="status">
  641. <NSelect v-model:value={forms.kt.status} options={[
  642. { label: '是', value: true },
  643. { label: '否', value: false }
  644. ] as any} />
  645. </NFormItem>
  646. </NGi>
  647. <NGi>
  648. <NFormItem label='排序' path="sortNo">
  649. <NInputNumber min={0} max={9999} v-model:value={forms.kt.sortNo} showButton={false} />
  650. </NFormItem>
  651. </NGi>
  652. </NGrid>
  653. </NGi>
  654. </NGrid>}
  655. <NSpace justify="end" style={'margin-top: 10px'}>
  656. <NButton type="default" onClick={() => emit('close', true)}>
  657. 取消
  658. </NButton>
  659. <NButton
  660. type="primary"
  661. onClick={() => onSubmit()}
  662. loading={btnLoading.value}
  663. disabled={btnLoading.value}
  664. >
  665. 确认
  666. </NButton>
  667. </NSpace>
  668. </NForm>
  669. </NSpin>
  670. },
  671. })