index.tsx 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. import ColCropper from '@/components/col-cropper'
  2. import ColUpload from '@/components/col-upload'
  3. import request from '@/helpers/request'
  4. import { verifyNumberIntegerAndFloat } from '@/helpers/toolsValidate'
  5. import {
  6. ElButton,
  7. ElForm,
  8. ElFormItem,
  9. ElInput,
  10. ElOption,
  11. ElOptionGroup,
  12. ElRadioButton,
  13. ElRadioGroup,
  14. ElSelect,
  15. ElDialog,
  16. ElMessage
  17. } from 'element-plus'
  18. import { defineComponent } from 'vue'
  19. import styles from './index.module.less'
  20. export type BackgroundMp3 = {
  21. url?: string
  22. track?: string
  23. }
  24. export const validator = (rule, value, callback) => {
  25. console.log(value)
  26. if (value == '') {
  27. callback(new Error('请输入收费价格'))
  28. } else if (Number(value) <= 0) {
  29. callback(new Error('收费金额必须大于0'))
  30. } else {
  31. callback()
  32. }
  33. }
  34. export default defineComponent({
  35. name: 'music-operation',
  36. data() {
  37. const query = this.$route.query
  38. return {
  39. type: query.type || 'create',
  40. subjectList: [],
  41. tagList: [],
  42. submitLoading: false,
  43. reason: '',
  44. form: {
  45. titleImg: '',
  46. accompanimentType: 'HOMEMODE',
  47. audioType: 'MP3',
  48. xmlFileUrl: '',
  49. hasBeat: 0,
  50. mp3Url: '',
  51. bgmp3Url: '',
  52. midiUrl: '',
  53. musicSheetName: '',
  54. composer: '',
  55. musicSubject: null as any,
  56. tags: [] as string[],
  57. notation: 0,
  58. canEvaluate: 1,
  59. showFingering: 1,
  60. chargeType: 0,
  61. musicPrice: '',
  62. backgroundMp3s: [
  63. {
  64. url: '',
  65. track: ''
  66. }
  67. ] as BackgroundMp3[]
  68. },
  69. radioList: [], // 选中的人数
  70. tagStatus: false,
  71. music_sheet_service_fee: 0
  72. }
  73. },
  74. async mounted() {
  75. document.title = this.type === 'create' ? '新建曲谱' : '编辑曲谱'
  76. try {
  77. await request
  78. .get('/api-website/sysConfig/queryByParamName', {
  79. params: {
  80. paramName: 'music_sheet_service_fee'
  81. }
  82. })
  83. .then(res => (this.music_sheet_service_fee = res.data.paramValue))
  84. await request.get('/api-website/open/subject/subjectSelect').then(res => {
  85. this.subjectList = res.data || []
  86. })
  87. await request.get('/api-website/open/MusicTag/tree').then(res => {
  88. this.tagList = res.data || []
  89. })
  90. if (this.$route.query.id) {
  91. this.setDetail(this.$route.query.id as string)
  92. }
  93. } catch {}
  94. },
  95. methods: {
  96. async setDetail(id: string) {
  97. try {
  98. const res = await request.get(
  99. '/api-website/open/music/sheet/detail/' + id
  100. )
  101. this.form.chargeType = res.data.chargeType === 'FREE' ? 0 : 2
  102. this.form.showFingering = res.data.showFingering
  103. this.form.notation = res.data.notation
  104. this.form.canEvaluate = res.data.canEvaluate
  105. if (this.form.chargeType) {
  106. this.form.musicPrice = res.data.musicPrice
  107. }
  108. this.form.composer = res.data.composer
  109. this.form.musicSheetName = res.data.musicSheetName
  110. this.form.audioType = res.data.audioType
  111. this.form.musicSubject = Number(res.data.musicSubject)
  112. const musicTag = res.data.musicTag.split(',')
  113. this.form.tags = musicTag.map((item: any) => {
  114. return Number(item)
  115. })
  116. this.radioList = this.form.tags as any
  117. this.form.xmlFileUrl = res.data.xmlFileUrl
  118. this.form.accompanimentType = res.data.accompanimentType
  119. this.form.titleImg = res.data.titleImg
  120. this.form.audioType = res.data.mp3Type
  121. if (this.form.audioType === 'MP3') {
  122. this.form.hasBeat = res.data.hasBeat || 0
  123. this.form.mp3Url = res.data.metronomeUrl || res.data.url
  124. } else {
  125. this.form.midiUrl = res.data.midiUrl
  126. }
  127. this.form.backgroundMp3s = (res.data.background || []).map(
  128. (item: any, index: any) => {
  129. if (index === 0) {
  130. this.form.bgmp3Url = item.metronomeUrl || item.audioFileUrl
  131. }
  132. return {
  133. url: this.form.hasBeat ? item.metronomeUrl : item.audioFileUrl,
  134. track: item.track
  135. }
  136. }
  137. )
  138. this.reason = res.data.reason
  139. console.log(this.form.bgmp3Url)
  140. } catch (error) {
  141. console.log(error)
  142. }
  143. },
  144. createSubmitData() {
  145. const { form } = this
  146. const beatType = form.hasBeat ? 'MP3_METRONOME' : 'MP3'
  147. const mp3Type = form.audioType === 'MP3' ? beatType : 'MIDI'
  148. return {
  149. audioType: form.audioType,
  150. sourceType: 'TEACHER',
  151. mp3Type,
  152. accompanimentType: form.accompanimentType,
  153. titleImg: form.titleImg,
  154. hasBeat: form.hasBeat,
  155. url: form.hasBeat ? '' : form.mp3Url,
  156. metronomeUrl: form.hasBeat ? form.mp3Url : '',
  157. showFingering: Number(form.showFingering),
  158. notation: Number(form.notation),
  159. musicTag: form.tags.join(','),
  160. musicSubject: form.musicSubject || undefined,
  161. musicSheetName: form.musicSheetName,
  162. midiUrl: form.midiUrl,
  163. xmlFileUrl: form.xmlFileUrl,
  164. canEvaluate: Number(form.canEvaluate),
  165. chargeType: form.chargeType === 0 ? 'FREE' : 'CHARGE',
  166. composer: form.composer,
  167. musicPrice: form.musicPrice,
  168. background: form.backgroundMp3s.map(item => ({
  169. audioFileUrl: form.hasBeat ? '' : form.bgmp3Url,
  170. track: item.track,
  171. metronomeUrl: form.hasBeat ? form.bgmp3Url : ''
  172. }))
  173. }
  174. },
  175. onFormatter(e: any) {
  176. e.target.value = verifyNumberIntegerAndFloat(e.target.value)
  177. },
  178. onSubmit() {
  179. ;(this as any).$refs.form.validate(async (valid: any) => {
  180. if (valid) {
  181. this.submitLoading = true
  182. console.log(this.createSubmitData(), 'createSubmitData')
  183. try {
  184. if (this.$route.query.id) {
  185. await request.post('/api-website/music/sheet/update', {
  186. data: {
  187. ...this.createSubmitData(),
  188. id: this.$route.query.id
  189. }
  190. })
  191. } else {
  192. await request.post('/api-website/music/sheet/create', {
  193. data: this.createSubmitData()
  194. })
  195. }
  196. this.submitLoading = false
  197. ElMessage.success('上传成功')
  198. sessionStorage.setItem('musicActiveName', 'DOING')
  199. this.$router.back()
  200. } catch (error) {
  201. this.submitLoading = false
  202. }
  203. } else {
  204. this.$nextTick(() => {
  205. const isError = document.getElementsByClassName('is-error')
  206. isError[0].scrollIntoView({
  207. block: 'center',
  208. behavior: 'smooth'
  209. })
  210. })
  211. return false
  212. }
  213. })
  214. },
  215. onDetail(type: string) {
  216. let url = `${location.origin}/teacher/#/registerProtocol`
  217. if (type === 'question') {
  218. url = `${location.origin}/teacher/muic-standard/question.html`
  219. } else if (type === 'music') {
  220. url = `${location.origin}/teacher/muic-standard/index.html`
  221. }
  222. window.open(url)
  223. }
  224. },
  225. render() {
  226. return (
  227. <div class={styles.form}>
  228. <div class="text-2xl font-semibold text-black leading-none px-6 py-5 ">
  229. {this.type === 'create' ? '新建曲谱' : '编辑曲谱'}
  230. </div>
  231. <ElForm
  232. size="large"
  233. labelPosition="left"
  234. labelWidth={'150px'}
  235. model={this.form}
  236. ref="form"
  237. class="px-7 py-5"
  238. >
  239. <div class={styles.tips}>
  240. <div class={styles.tipsTitle}>注意事项:</div>
  241. <div class={styles.tipsContent}>
  242. 1、必须是上传人自己参与制作的作品。
  243. <br />
  244. 2、歌曲及歌曲信息中请勿涉及政治、宗教、广告、涉毒、犯罪、色情、低俗、暴力、血腥、消极等违规内容,违反者直接删除内容。多次违反将封号。
  245. <br />
  246. 3、点击查看{' '}
  247. <span onClick={() => this.onDetail('protocol')}>
  248. 《用户注册协议》
  249. </span>
  250. ,如果您上传了文件,即认为您完全同意并遵守该协议的内容;
  251. </div>
  252. </div>
  253. <ElFormItem
  254. label="上传XML"
  255. prop="xmlFileUrl"
  256. rules={[{ required: true, message: '请选择MusicXML文件' }]}
  257. >
  258. <ColUpload
  259. v-model:modelValue={this.form.xmlFileUrl}
  260. bucket={'cloud-coach'}
  261. accept={'application/xml'}
  262. uploadType={'file'}
  263. extraTips="文件最大不能超过5MB"
  264. />
  265. </ElFormItem>
  266. <div class={styles.tips}>
  267. <div class={styles.tipsTitle}>曲谱审核标准:</div>
  268. <div class={styles.tipsContent}>
  269. 1、文件大小不要超过5MB,不符合版面规范的乐谱,审核未通过的不予上架,详情参考
  270. <span onClick={() => this.onDetail('music')}>
  271. 《曲谱排版规范》
  272. </span>
  273. ; 1、必须是上传人自己参与制作的作品。
  274. <br />
  275. 2、XML与MIDI文件内容必须一致,推荐使用Sibelius打谱软件。导出设置:导出XML-未压缩(*.xml)/导出MIDI:音色-其他回放设备General
  276. MIDI、MIDI、MIDI文件类型-类型0、不要勾选“将弱拍小节导出为具有休止符的完整小节”。点击查看
  277. <span onClick={() => this.onDetail('question')}>
  278. 《常见问题》
  279. </span>
  280. </div>
  281. </div>
  282. <ElFormItem
  283. label="播放类型"
  284. prop="audioType"
  285. rules={[{ required: true, message: '请选择播放类型' }]}
  286. >
  287. <ElRadioGroup v-model={this.form.audioType}>
  288. <ElRadioButton label={'MIDI'} class="mr-3 w-24">
  289. MIDI
  290. </ElRadioButton>
  291. <ElRadioButton label={'MP3'} class="w-24">
  292. MP3
  293. </ElRadioButton>
  294. </ElRadioGroup>
  295. </ElFormItem>
  296. {this.form.audioType === 'MP3' ? (
  297. <>
  298. <ElFormItem
  299. label="是否带节拍器"
  300. prop="hasBeat"
  301. rules={[{ required: true, message: '请选择是否带节拍器' }]}
  302. >
  303. <ElRadioGroup v-model={this.form.hasBeat}>
  304. <ElRadioButton label={0} class="mr-3 w-24">
  305. </ElRadioButton>
  306. <ElRadioButton label={1} class="w-24">
  307. </ElRadioButton>
  308. </ElRadioGroup>
  309. </ElFormItem>
  310. <ElFormItem
  311. label="是否带节拍器"
  312. prop="accompanimentType"
  313. rules={[{ required: true, message: '请选择是否带节拍器' }]}
  314. >
  315. <ElRadioGroup v-model={this.form.accompanimentType}>
  316. <ElRadioButton label={'HOMEMODE'} class="mr-3 w-24">
  317. 自制伴奏
  318. </ElRadioButton>
  319. <ElRadioButton label={'COMMON'} class="w-24">
  320. 普通伴奏
  321. </ElRadioButton>
  322. </ElRadioGroup>
  323. </ElFormItem>
  324. <ElFormItem label="伴奏文件" prop="mp3Url">
  325. <ColUpload
  326. v-model:modelValue={this.form.mp3Url}
  327. bucket={'cloud-coach'}
  328. accept={'.mp3'}
  329. uploadType={'file'}
  330. size={8}
  331. extraTips="文件最大不能超过8MB"
  332. />
  333. </ElFormItem>
  334. </>
  335. ) : (
  336. <>
  337. <ElFormItem
  338. label="伴奏类型"
  339. prop="accompanimentType"
  340. rules={[{ required: true, message: '请选择伴奏类型' }]}
  341. >
  342. <ElRadioGroup v-model={this.form.accompanimentType}>
  343. <ElRadioButton label={'HOMEMODE'} class="mr-3 w-24">
  344. 自制伴奏
  345. </ElRadioButton>
  346. <ElRadioButton label={'COMMON'} class="w-24">
  347. 普通伴奏
  348. </ElRadioButton>
  349. </ElRadioGroup>
  350. </ElFormItem>
  351. <ElFormItem
  352. label="MIDI文件"
  353. prop="midiUrl"
  354. rules={[{ required: true, message: '请选择MIDI文件' }]}
  355. >
  356. <ColUpload
  357. v-model:modelValue={this.form.midiUrl}
  358. bucket={'cloud-coach'}
  359. accept={'.midi'}
  360. uploadType={'file'}
  361. size={8}
  362. extraTips="文件最大不能超过8MB"
  363. />
  364. </ElFormItem>
  365. </>
  366. )}
  367. <div class={styles.tips}>
  368. <div class={styles.tipsContent}>
  369. 1、推荐上传自制伴奏,伴奏和谱面必须对齐。自制伴奏可以设置更高的收费标准。
  370. <br />
  371. 2、普通伴奏如果涉及到版权纠纷,根据
  372. <span onClick={() => this.onDetail('protocol')}>
  373. 《用户注册协议》
  374. </span>
  375. 平台有权进行下架处理。
  376. </div>
  377. </div>
  378. {this.form.audioType === 'MP3' && (
  379. <ElFormItem
  380. label="原音文件"
  381. prop="bgmp3Url"
  382. rules={[{ required: true, message: '请选择原音文件' }]}
  383. >
  384. <ColUpload
  385. v-model:modelValue={this.form.bgmp3Url}
  386. bucket={'cloud-coach'}
  387. accept={'.mp3'}
  388. uploadType={'file'}
  389. extraTips="文件最大不能超过8MB"
  390. />
  391. </ElFormItem>
  392. )}
  393. <ElFormItem
  394. label="曲目名称"
  395. prop="musicSheetName"
  396. rules={[{ required: true, message: '请输入曲目名称' }]}
  397. >
  398. <ElInput
  399. v-model={this.form.musicSheetName}
  400. placeholder="请选择曲目名称"
  401. />
  402. </ElFormItem>
  403. <div class={styles.tips}>
  404. <div class={styles.tipsContent}>
  405. 1、同一首曲目不可重复上传,如有不同版本统一用“()”补充。举例:人生的旋转木马(长笛二重奏版)。
  406. <br />
  407. 2、曲目名后可添加曲目信息备注,包含但不限于曲目类型等。曲目名《xxxx》,举例:人生的旋转木马《哈尔的移动城堡》(长笛二重奏版)
  408. <br />
  409. 3、其他信息不要写在曲目名里,如歌手、上传人员昵称等。
  410. </div>
  411. </div>
  412. <ElFormItem
  413. label="曲谱封面"
  414. prop="titleImg"
  415. rules={[
  416. {
  417. required: true,
  418. message: '请上传曲谱封面'
  419. }
  420. ]}
  421. >
  422. <ColCropper
  423. modelValue={this.form.titleImg}
  424. bucket={'cloud-coach'}
  425. cropUploadSuccess={(data: any) => {
  426. this.form.titleImg = data
  427. }}
  428. domSize={{ height: '150px' }}
  429. options={{
  430. title: '曲谱封面',
  431. enlarge: 2,
  432. autoCropWidth: 300,
  433. autoCropHeight: 300
  434. }}
  435. />
  436. </ElFormItem>
  437. <ElFormItem
  438. label="艺术家"
  439. prop="composer"
  440. rules={[{ required: true, message: '请输入艺术家' }]}
  441. >
  442. <ElInput v-model={this.form.composer} placeholder="请输入艺术家" />
  443. </ElFormItem>
  444. <ElFormItem
  445. label="曲目声部"
  446. prop="musicSubject"
  447. rules={[
  448. { required: true, message: '请选择曲目声部', trigger: 'change' }
  449. ]}
  450. >
  451. <ElSelect
  452. filterable
  453. v-model={this.form.musicSubject}
  454. placeholder="请选择曲目声部"
  455. class="w-full"
  456. >
  457. {this.subjectList.map((group: any) => (
  458. <ElOptionGroup key={group.id} label={group.name}>
  459. {group.subjects &&
  460. group.subjects.map((item: any) => (
  461. <ElOption
  462. key={item.id}
  463. value={item.id}
  464. label={item.name}
  465. />
  466. ))}
  467. </ElOptionGroup>
  468. ))}
  469. </ElSelect>
  470. </ElFormItem>
  471. <div class={styles.tips}>
  472. <div class={styles.tipsContent}>
  473. XML文件中,选择的曲目声部需要在总谱的置顶位置。
  474. </div>
  475. </div>
  476. <ElFormItem
  477. label="曲目标签"
  478. prop="tags"
  479. rules={[{ required: true, message: '请选择曲目标签' }]}
  480. >
  481. <div class="w-full relative">
  482. <div
  483. class=" w-full block h-[42px] absolute top-0 left-0 z-10"
  484. onClick={() => {
  485. console.log(111)
  486. this.tagStatus = true
  487. }}
  488. ></div>
  489. <ElSelect
  490. multiple
  491. v-model={this.form.tags}
  492. placeholder="请选择曲目标签"
  493. class="w-full"
  494. >
  495. {this.tagList.map((group: any) => (
  496. <ElOptionGroup key={group.id} label={group.name}>
  497. {group.children &&
  498. group.children.map((item: any) => (
  499. <ElOption
  500. key={item.id}
  501. value={item.id}
  502. label={item.name}
  503. />
  504. ))}
  505. </ElOptionGroup>
  506. ))}
  507. </ElSelect>
  508. </div>
  509. </ElFormItem>
  510. <ElFormItem
  511. label="支持简谱"
  512. prop="notation"
  513. rules={[{ required: true, message: '请选择是否支持简谱' }]}
  514. >
  515. <ElRadioGroup v-model={this.form.notation}>
  516. <ElRadioButton label={0} class="mr-3 w-24">
  517. </ElRadioButton>
  518. <ElRadioButton label={1} class="w-24">
  519. </ElRadioButton>
  520. </ElRadioGroup>
  521. </ElFormItem>
  522. <ElFormItem
  523. label="是否评测"
  524. prop="canEvaluate"
  525. rules={[{ required: true, message: '请选择是否评测' }]}
  526. >
  527. <ElRadioGroup v-model={this.form.canEvaluate}>
  528. <ElRadioButton label={0} class="mr-3 w-24">
  529. </ElRadioButton>
  530. <ElRadioButton label={1} class="w-24">
  531. </ElRadioButton>
  532. </ElRadioGroup>
  533. </ElFormItem>
  534. <ElFormItem
  535. label="指法展示"
  536. prop="showFingering"
  537. rules={[{ required: true, message: '请选择指法展示' }]}
  538. >
  539. <ElRadioGroup v-model={this.form.showFingering}>
  540. <ElRadioButton label={0} class="mr-3 w-24">
  541. </ElRadioButton>
  542. <ElRadioButton label={1} class="w-24">
  543. </ElRadioButton>
  544. </ElRadioGroup>
  545. </ElFormItem>
  546. <ElFormItem
  547. label="是否收费"
  548. prop="chargeType"
  549. rules={[{ required: true, message: '请选择是否收费' }]}
  550. >
  551. <ElRadioGroup v-model={this.form.chargeType}>
  552. <ElRadioButton label={0} class="mr-3 w-24">
  553. </ElRadioButton>
  554. <ElRadioButton label={2} class="w-24">
  555. </ElRadioButton>
  556. </ElRadioGroup>
  557. </ElFormItem>
  558. {this.form.chargeType === 2 && (
  559. <>
  560. <ElFormItem
  561. label="收费价格"
  562. prop="musicPrice"
  563. rules={[{ required: true, validator }]}
  564. >
  565. <ElInput
  566. v-model={this.form.musicPrice}
  567. placeholder="请输入收费价格"
  568. // @ts-ignore
  569. maxlength={5}
  570. onKeyup={this.onFormatter}
  571. v-slots={{
  572. suffix: () => <span class="text-base text-[#999]">元</span>
  573. }}
  574. />
  575. </ElFormItem>
  576. <ElFormItem>
  577. <div class={styles.rule}>
  578. <p>扣除手续费后该曲目预计收入为:</p>
  579. <p>
  580. 每人:
  581. <span>
  582. {((parseFloat(this.form.musicPrice || '0') || 0) *
  583. (100 - this.music_sheet_service_fee)) /
  584. 100}
  585. </span>
  586. 元/人
  587. </p>
  588. <p>您的乐谱收入将在学员购买后结算到您的账户中</p>
  589. </div>
  590. </ElFormItem>
  591. </>
  592. )}
  593. </ElForm>
  594. <div class="text-center pt-6 pb-7">
  595. <ElButton
  596. class="!w-44 !h-[48px]"
  597. round
  598. onClick={() => {
  599. this.$router.back()
  600. }}
  601. >
  602. 取消
  603. </ElButton>
  604. <ElButton
  605. type="primary"
  606. class="!w-44 !h-[48px]"
  607. round
  608. onClick={this.onSubmit}
  609. loading={this.submitLoading}
  610. >
  611. 提交审核
  612. </ElButton>
  613. </div>
  614. <ElDialog
  615. modelValue={this.tagStatus}
  616. onUpdate:modelValue={val => (this.tagStatus = val)}
  617. width="35%"
  618. title="全部标签"
  619. >
  620. {this.tagList.map((item: any, index: number) => (
  621. <div class={[styles.tags, 'py-2']}>
  622. <div class="text-sm pb-2">{item.name}</div>
  623. {item.children.map((child: any) => (
  624. <ElRadioGroup v-model={this.radioList[index]} class="pb-2">
  625. <ElRadioButton label={child.id} class="mr-3">
  626. {child.name}
  627. </ElRadioButton>
  628. </ElRadioGroup>
  629. ))}
  630. </div>
  631. ))}
  632. <div class="text-center pt-2">
  633. <ElButton
  634. class="!w-36 !h-[48px]"
  635. round
  636. size="large"
  637. onClick={() => {
  638. this.radioList = []
  639. }}
  640. >
  641. 重置
  642. </ElButton>
  643. <ElButton
  644. class="!w-36 !h-[48px]"
  645. round
  646. size="large"
  647. type="primary"
  648. onClick={() => {
  649. this.form.tags = this.radioList
  650. this.tagStatus = false
  651. ;(this as any).$refs.form.clearValidate('tags')
  652. }}
  653. >
  654. 确认
  655. </ElButton>
  656. </div>
  657. </ElDialog>
  658. </div>
  659. )
  660. }
  661. })