Prechádzať zdrojové kódy

添加创建视频课

lex 2 rokov pred
rodič
commit
54b19e0c76

BIN
src/common/images/icon_music_active.png


+ 1 - 1
src/components/musicLIstItem/index.module.less

@@ -138,7 +138,7 @@
     display: flex;
     flex-direction: column;
     align-items: flex-end;
-    // justify-content: center;
+    justify-content: center;
     cursor: pointer;
 
     .favoriteWrap {

+ 20 - 5
src/components/musicLIstItem/index.tsx

@@ -39,6 +39,14 @@ export default defineComponent({
       type: Object as () => Props,
       default: () => ({})
     },
+    hiddenCollect: {
+      type: Boolean,
+      defualt: false
+    },
+    isClick: {
+      type: Boolean,
+      default: false
+    },
     onClick: {
       type: Function,
       default: (item: any) => {}
@@ -56,6 +64,7 @@ export default defineComponent({
         state.item = item
       }
     )
+
     const gotoMusicDetail = () => {
       router.push({ path: '/muiscDetial', query: { id: state.item.id } })
     }
@@ -66,7 +75,10 @@ export default defineComponent({
           props.onClick(state.item)
         }}
       >
-        <div class={classes.itemWrap} onClick={() => gotoMusicDetail()}>
+        <div
+          class={classes.itemWrap}
+          onClick={() => !props.isClick && gotoMusicDetail()}
+        >
           <div class={classes.left}>
             <div class={classes.imgWrap}>
               <img src={state.item.titleImg || music} alt="" />
@@ -102,10 +114,13 @@ export default defineComponent({
           </div>
 
           <div class={classes.right}>
-            <div class={classes.favoriteWrap}>
-              <span>{state.item.favoriteCount | 0} 收藏</span>
-              <img src={state.item.favorite ? lineStart : start} alt="" />
-            </div>
+            {!props.hiddenCollect && (
+              <div class={classes.favoriteWrap}>
+                <span>{state.item.favoriteCount | 0} 收藏</span>
+                <img src={state.item.favorite ? lineStart : start} alt="" />
+              </div>
+            )}
+
             <div class={classes.tagList}>
               {state.item.subjectNames ? (
                 <div class={classes.tag}>{state.item.subjectNames}</div>

+ 8 - 5
src/views/student-info/components/item/index.tsx

@@ -3,7 +3,9 @@ import { defineComponent } from 'vue'
 import pan from '../../images/pan.png'
 import start from '../../images/start.png'
 import hold from '../../images/hold.png'
-import iconStart from '../../images/icon_start.png'
+// import iconStart from '../../images/icon_start.png'
+import iconStartActive from '@/components/albumItem/images/lineStart.png'
+import iconStart from '@/components/albumItem/images/start.png'
 import styles from './index.module.less'
 
 export default defineComponent({
@@ -30,18 +32,19 @@ export default defineComponent({
         {item.paymentType === 'CHARGE' && (
           <span class={styles.albumType}>付费</span>
         )}
-        <ElImage src={iconStart} class="w-6 h-6 !absolute top-2 right-4 z-10" />
-
+        {/* favorite */}
+        <ElImage
+          src={item.favorite ? iconStartActive : iconStart}
+          class="w-6 h-6 !absolute top-2 right-4 z-10"
+        />
         <ElImage
           class="w-full h-[156px] align-middle rounded-[10px]"
           fit="cover"
           src={item.albumCoverUrl || hold}
         />
-
         <div class="text-lg text-black whitespace-nowrap text-ellipsis overflow-hidden pb-0.5 pt-2">
           {item.albumName}
         </div>
-
         <div class="flex justify-between text-sm text-[#999]">
           <div class="flex items-center">
             {/* <img src={pan} class="w-[18px] h-[18px] mr-1" /> */}

+ 13 - 1
src/views/user-info/video-operation/course-content/index.module.less

@@ -12,7 +12,6 @@
       color: rgba(0, 0, 0, 0.85);
     }
     .el-dialog {
-      --el-dialog-width: 375px !important;
       border-radius: 10px;
       overflow: hidden;
     }
@@ -30,4 +29,17 @@
       min-width: auto;
     }
   }
+
+  .selectMusicAlbum {
+    // --el-dialog-width: 700px !important;
+  }
+
+  .relationList {
+    width: 100%;
+    height: 48px;
+    position: absolute;
+    top: 0;
+    z-index: 99;
+    right: 0;
+  }
 }

+ 62 - 12
src/views/user-info/video-operation/course-content/index.tsx

@@ -15,6 +15,7 @@ import {
   ElRow,
   ElTooltip
 } from 'element-plus'
+import { ArrowDown } from '@element-plus/icons-vue'
 import { defineComponent } from 'vue'
 import CoursePreview from '../course-preview'
 import { createState } from '../createState'
@@ -23,6 +24,7 @@ import iconDown from '../images/icon_down.png'
 import iconUp from '../images/icon_up.png'
 import iconDelete from '../images/icon_delete.png'
 import ColVideo from '@/components/col-video'
+import SelectMusicAlbum from '../select-music-album'
 
 export default defineComponent({
   name: 'course-content',
@@ -36,10 +38,13 @@ export default defineComponent({
             videoTitle: '',
             videoContent: '',
             videoUrl: '',
+            relationList: [] as any,
             coverUrl: ''
           }
         ] as any
-      }
+      },
+      musicStatus: false,
+      selectItem: {} as any // 选中的课程
     }
   },
   methods: {
@@ -52,6 +57,7 @@ export default defineComponent({
           videoTitle: '',
           videoContent: '',
           videoUrl: item,
+          relationList: [] as any,
           coverUrl: ''
         })
       })
@@ -68,7 +74,7 @@ export default defineComponent({
           this.show = true
         } else {
           this.$nextTick(() => {
-            let isError = document.getElementsByClassName('is-error')
+            const isError = document.getElementsByClassName('is-error')
             isError[0].scrollIntoView({
               block: 'center',
               behavior: 'smooth'
@@ -81,7 +87,7 @@ export default defineComponent({
     async createSubmit() {
       try {
         const videoDetail = createState.lessonGroup
-        let params = {
+        const params = {
           lessonList: createState.lessonList,
           lessonGroup: {
             ...videoDetail,
@@ -102,11 +108,21 @@ export default defineComponent({
         }
         sessionStorage.setItem('videoActiveName', 'DOING')
         this.$router.back()
-      } catch {}
+      } catch {
+        //
+      }
     },
     swapItems(arr: any, index1: number, index2: number) {
       arr[index1] = arr.splice(index2, 1, arr[index1])[0]
       return arr
+    },
+    getName(item: any) {
+      const relation =
+        item.relationList.length > 0 ? item.relationList[0] : null
+      return relation
+        ? (relation.relationMusicAlbum === 'ALBUM' ? '专辑:' : '曲目:') +
+            relation.musicAlbumName
+        : ''
     }
   },
   render() {
@@ -115,7 +131,7 @@ export default defineComponent({
         <ElForm
           class="px-6 pb-10 pt-7 min-h-[280px]"
           size="large"
-          labelWidth={'120px'}
+          labelWidth={'140px'}
           labelPosition="left"
           ref="form"
           model={createState}
@@ -239,23 +255,17 @@ export default defineComponent({
               </ElFormItem>
               <ElRow>
                 <ElCol span={12}>
-                  {/* <ElFormItem label={`第${index + 1}课`}> */}
                   <ElFormItem label="课程视频" required>
-                    {/* <ColUploadVideo
-                      v-model:modelValue={item.videoUrl}
-                      disabled
-                    /> */}
                     <ColVideo
                       styleValue={{ with: '150px', height: '85px' }}
                       controls={false}
                       src={item.videoUrl}
-                      // progress={false}
                       volume={false}
                     />
                     <p></p>
                   </ElFormItem>
                 </ElCol>
-                <ElCol span={10}>
+                <ElCol span={11}>
                   <ElFormItem
                     label="视频封面"
                     prop={`lessonList.${index}.coverUrl`}
@@ -268,6 +278,25 @@ export default defineComponent({
                   </ElFormItem>
                 </ElCol>
               </ElRow>
+              <ElFormItem
+                label="关联曲目或专辑"
+                prop={`lessonList.${index}.relationList`}
+                onClick={() => {
+                  this.selectItem = item
+                  this.musicStatus = true
+                }}
+              >
+                <div class={styles.relationList}></div>
+                <ElInput
+                  placeholder="请选择关联曲目或专辑"
+                  // v-model={item.videoContent}
+                  modelValue={
+                    item.relationList.length > 0 ? this.getName(item) : ''
+                  }
+                  readonly
+                  suffixIcon={ArrowDown}
+                />
+              </ElFormItem>
             </div>
           ))}
         </ElForm>
@@ -296,6 +325,7 @@ export default defineComponent({
         {/*  @ts-ignore */}
         <ElDialog
           v-model={this.show}
+          width={375}
           title="预览"
           v-slots={{
             footer: () => (
@@ -323,6 +353,26 @@ export default defineComponent({
         >
           <CoursePreview />
         </ElDialog>
+
+        <ElDialog v-model={this.musicStatus} title="选择曲目或专辑" width={750}>
+          <SelectMusicAlbum
+            subjectIds={createState.lessonGroup.lessonSubject}
+            onSelect={(item: any) => {
+              this.musicStatus = false
+              this.selectItem.relationList = [
+                {
+                  musicAlbumId: item.id,
+                  musicAlbumName:
+                    item.selectType === 'ALBUM'
+                      ? item.albumName
+                      : item.musicSheetName,
+                  relationMusicAlbum: item.selectType,
+                  useRelationType: 'RECOMMEND'
+                }
+              ]
+            }}
+          />
+        </ElDialog>
       </div>
     )
   }

+ 43 - 0
src/views/user-info/video-operation/course-preview/index.module.less

@@ -45,6 +45,13 @@
       line-height: 22px;
       display: flex;
       align-items: center;
+
+      .userName {
+        max-width: 80px;
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+      }
     }
 
     .buyNum {
@@ -130,3 +137,39 @@
     -webkit-box-orient: vertical;
   }
 }
+
+.infoVideo {
+  margin-top: 10px;
+  padding: 8px 10px;
+  border-radius: 6px;
+  font-size: 13px;
+  line-height: 1;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  & > div {
+    display: flex;
+    align-items: center;
+  }
+  img {
+    width: 16px;
+    height: 16px;
+  }
+  span {
+    padding-left: 8px;
+    max-width: 240px;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+
+  &.albumInfo {
+    background: #e0f7f3;
+    color: #2dc7aa;
+  }
+
+  &.musicInfo {
+    background: #ffefe0;
+    color: #ff8900;
+  }
+}

+ 65 - 23
src/views/user-info/video-operation/course-preview/index.tsx

@@ -7,6 +7,9 @@ import defaultIcon from '@common/images/icon_teacher.png'
 import iconIn from '../images/icon_course_introduction.png'
 import iconList from '../images/icon_course_list.png'
 import videoStop from '../images/icon_video_stop.png'
+import iconAlbum from '@common/images/icon_album_active.png'
+import iconMusic from '@common/images/icon_music_active.png'
+import { ArrowRight } from '@element-plus/icons-vue'
 
 export default defineComponent({
   name: 'course-preview',
@@ -29,6 +32,9 @@ export default defineComponent({
     },
     lessonList() {
       return createState.lessonList || []
+    },
+    musicAlbumInfos() {
+      return []
     }
   },
   render() {
@@ -53,7 +59,9 @@ export default defineComponent({
                   fit=""
                 />
                 <div class={styles.name}>
-                  {this.userInfo.username || `游客${this.userInfo.id || ''}`}
+                  <div class={styles.userName}>
+                    {this.userInfo.username || `游客${this.userInfo.id || ''}`}
+                  </div>
 
                   <div class={styles.buyNum}>
                     {this.userInfo.buyNum}人已购买
@@ -101,30 +109,64 @@ export default defineComponent({
 
           <div class="mx-[10px] pt-[10px] pb-4 text-sm text-[#7A7A7A] border-t border-t-[#EBEBEB] flex flex-col">
             {createState.lessonList.map((item: any) => (
-              <div class="flex mb-3">
-                <div class={styles.videoImg}>
-                  <ElImage
-                    class="align-middle h-[70px] w-[100px] rounded overflow-hidden"
-                    src={item.coverUrl}
-                    fit="cover"
-                  />
-                  <ElIcon class={styles.videoStop} size={26}>
-                    <img src={videoStop} />
-                  </ElIcon>
-                </div>
+              <>
+                <div class="flex">
+                  <div class={styles.videoImg}>
+                    <ElImage
+                      class="align-middle h-[70px] w-[100px] rounded overflow-hidden"
+                      src={item.coverUrl}
+                      fit="cover"
+                    />
+                    <ElIcon class={styles.videoStop} size={26}>
+                      <img src={videoStop} />
+                    </ElIcon>
+                  </div>
 
-                <div class={[styles.videoTitle, '!h-[70px]']}>
-                  <p
-                    class={[
-                      styles.videoTitleText,
-                      'whitespace-nowrap overflow-hidden text-ellipsis'
-                    ]}
-                  >
-                    {item.videoTitle}
-                  </p>
-                  <p class={[styles.videoTitleContent]}>{item.videoContent}</p>
+                  <div class={[styles.videoTitle, '!h-[70px]']}>
+                    <p
+                      class={[
+                        styles.videoTitleText,
+                        'whitespace-nowrap overflow-hidden text-ellipsis'
+                      ]}
+                    >
+                      {item.videoTitle}
+                    </p>
+                    <p class={[styles.videoTitleContent]}>
+                      {item.videoContent}
+                    </p>
+                  </div>
                 </div>
-              </div>
+
+                {item.relationList &&
+                  item.relationList.map((info: any) => (
+                    <div
+                      class={[
+                        styles.infoVideo,
+                        info.relationMusicAlbum === 'ALBUM'
+                          ? styles.albumInfo
+                          : styles.musicInfo
+                      ]}
+                    >
+                      <div>
+                        <img
+                          src={
+                            info.relationMusicAlbum === 'ALBUM'
+                              ? iconAlbum
+                              : iconMusic
+                          }
+                        />
+                        {info.relationMusicAlbum === 'ALBUM' ? (
+                          <span>专辑:{info.musicAlbumName}</span>
+                        ) : (
+                          <span>曲目:{info.musicAlbumName}</span>
+                        )}
+                      </div>
+                      <ElIcon>
+                        <ArrowRight />
+                      </ElIcon>
+                    </div>
+                  ))}
+              </>
             ))}
           </div>
         </div>

+ 2 - 1
src/views/user-info/video-operation/createState.tsx

@@ -22,13 +22,14 @@ const original = () => {
       lessonPrice: null as any,
       lessonCoverUrl: '',
       lessonCoverTemplateUrl: ''
-    },
+    } as any,
     lessonList: [
       // {
       //   videoTitle: '',
       //   videoContent: '',
       //   videoUrl: '',
       //   coverUrl: '',
+      //   relationList: [],
       //   posterUrl: '' // 视频封面图
       // }
     ] as any

+ 10 - 0
src/views/user-info/video-operation/index.tsx

@@ -62,11 +62,21 @@ export default defineComponent({
 
       result.detailList &&
         result.detailList.forEach((item: any) => {
+          const tempInfo = item.musicAlbumInfos || []
+          const relationList = tempInfo.map((info: any) => {
+            return {
+              relationMusicAlbum: info.relationType,
+              musicAlbumName: info.name,
+              musicAlbumId: info.musicAlbumId,
+              relationId: info.id
+            }
+          })
           createState.lessonList.push({
             videoTitle: item.videoTitle,
             videoContent: item.videoContent,
             videoUrl: item.videoUrl,
             coverUrl: item.coverUrl,
+            relationList,
             posterUrl: item.posterUrl // 视频封面图
           })
         })

+ 179 - 0
src/views/user-info/video-operation/select-music-album/album-list.tsx

@@ -0,0 +1,179 @@
+import ColEmpty from '@/components/col-empty'
+import Pagination from '@/components/pagination'
+import request from '@/helpers/request'
+import styles from './index.module.less'
+import {
+  ElSkeleton,
+  ElSkeletonItem,
+  ElButton,
+  ElInput,
+  ElRow,
+  ElCol
+} from 'element-plus'
+import { defineComponent } from 'vue'
+import { getUserType } from '@/helpers/utils'
+import Item from '@/views/student-info/components/item'
+
+export default defineComponent({
+  name: 'album-list',
+  props: {
+    subjectIds: {
+      type: Number
+    },
+    onSelect: {
+      type: Function,
+      default: (item: any) => {}
+    }
+  },
+  data() {
+    return {
+      clientType: '',
+      idAndName: '',
+      pageInfo: {
+        // 分页规则
+        limit: 8, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [8, 16] // 选择限制显示条数
+      },
+      list: [] as any[],
+      loading: false,
+      dataShow: false // 是否有数据
+    }
+  },
+  mounted() {
+    const clientType = getUserType()
+    if (clientType === 'TEACHER') this.clientType = clientType
+    this.getList()
+  },
+  methods: {
+    onSearch() {
+      this.pageInfo.page = 1
+      this.list = []
+      this.dataShow = false
+      this.loading = false
+      this.getList()
+    },
+    async getList() {
+      this.loading = true
+      try {
+        const { data } = await request.post(
+          '/api-website/open/music/album/list',
+          {
+            data: {
+              idAndName: this.idAndName,
+              albumStatus: 1,
+              subjectIds: this.subjectIds,
+              page: this.pageInfo.page,
+              rows: this.pageInfo.limit,
+              clientType: this.clientType
+            },
+            params: {
+              clientType: getUserType()
+            }
+          }
+        )
+        this.list = data.rows || []
+        this.pageInfo.total = data.total
+        if (data.total <= 0) {
+          this.dataShow = true
+        }
+      } catch {}
+      if (this.dataShow) {
+        this.loading = false
+      } else {
+        setTimeout(() => {
+          this.loading = false
+        }, 200)
+      }
+    }
+  },
+  render() {
+    return (
+      <div class={styles.albumList}>
+        <ElRow style={{ paddingBottom: '16px' }}>
+          <ElCol span={12}>
+            <ElInput
+              placeholder="请输入专辑名称"
+              clearable
+              size="large"
+              v-model={this.idAndName}
+            />
+          </ElCol>
+          <ElCol span={11} offset={1}>
+            <ElButton
+              type="primary"
+              size="large"
+              onClick={() => {
+                this.onSearch()
+              }}
+            >
+              搜索
+            </ElButton>
+          </ElCol>
+        </ElRow>
+
+        <div class="flex flex-wrap">
+          <ElSkeleton
+            loading={this.loading}
+            animated
+            class="px-[14px] flex items-center flex-row justify-between"
+            count={4}
+            v-slots={{
+              template: () => (
+                <div class="flex items-center flex-col justify-between w-[156px]">
+                  <ElSkeletonItem
+                    variant="image"
+                    style={{ width: '156px', height: '156px' }}
+                  ></ElSkeletonItem>
+                  <ElSkeletonItem
+                    variant="p"
+                    style={{ width: '100%', margin: '4px 0' }}
+                  ></ElSkeletonItem>
+                  <div class="flex w-full justify-between">
+                    <ElSkeletonItem
+                      variant="p"
+                      style={{ width: '35%' }}
+                    ></ElSkeletonItem>
+
+                    <ElSkeletonItem
+                      variant="p"
+                      style={{ width: '35%' }}
+                    ></ElSkeletonItem>
+                  </div>
+                </div>
+              )
+            }}
+          >
+            {this.list.map((item: any) => (
+              <>
+                <div class="w-1/4 pb-5">
+                  <Item
+                    class="m-auto"
+                    item={item}
+                    onItemClick={(item: any) => {
+                      this.onSelect({
+                        selectType: 'ALBUM',
+                        ...item
+                      })
+                    }}
+                  />
+                </div>
+              </>
+            ))}
+          </ElSkeleton>
+        </div>
+
+        <Pagination
+          total={this.pageInfo.total}
+          v-model:page={this.pageInfo.page}
+          v-model:limit={this.pageInfo.limit}
+          pageSizes={this.pageInfo.page_size}
+          pagination={this.getList}
+        />
+
+        {this.dataShow && <ColEmpty />}
+      </div>
+    )
+  }
+})

+ 14 - 0
src/views/user-info/video-operation/select-music-album/index.module.less

@@ -0,0 +1,14 @@
+.albumList {
+  :global {
+    .el-button--large {
+      --el-button-size: 48px !important;
+    }
+
+    .el-pagination {
+      .el-input {
+        height: 32px;
+        line-height: 32px;
+      }
+    }
+  }
+}

+ 47 - 0
src/views/user-info/video-operation/select-music-album/index.tsx

@@ -0,0 +1,47 @@
+import { ElTabPane, ElTabs } from 'element-plus'
+import { defineComponent } from 'vue'
+import AlbumList from './album-list'
+import MusicList from './music-list'
+
+export default defineComponent({
+  name: 'select-music-album',
+  props: {
+    subjectIds: {
+      type: Number
+    },
+    onSelect: {
+      type: Function,
+      default: (item: any) => {}
+    }
+  },
+  data() {
+    return {
+      tabVal: 'music'
+    }
+  },
+
+  render() {
+    return (
+      <div style="padding: 0 16px 16px;">
+        <ElTabs v-model={this.tabVal}>
+          <ElTabPane label="曲目" name="music">
+            <MusicList
+              subjectIds={this.subjectIds}
+              onSelect={(item: any) => {
+                this.onSelect(item)
+              }}
+            />
+          </ElTabPane>
+          <ElTabPane label="专辑" name="album">
+            <AlbumList
+              subjectIds={this.subjectIds}
+              onSelect={(item: any) => {
+                this.onSelect(item)
+              }}
+            />
+          </ElTabPane>
+        </ElTabs>
+      </div>
+    )
+  }
+})

+ 175 - 0
src/views/user-info/video-operation/select-music-album/music-list.tsx

@@ -0,0 +1,175 @@
+import ColEmpty from '@/components/col-empty'
+import Pagination from '@/components/pagination'
+import request from '@/helpers/request'
+import styles from './index.module.less'
+import {
+  ElSkeleton,
+  ElSkeletonItem,
+  ElButton,
+  ElInput,
+  ElRow,
+  ElCol
+} from 'element-plus'
+import { defineComponent } from 'vue'
+import { getUserType } from '@/helpers/utils'
+import Item from '@/views/student-info/components/item'
+import musicLIstItem from '@/components/musicLIstItem'
+
+export default defineComponent({
+  name: 'album-list',
+  props: {
+    subjectIds: {
+      type: Number
+    },
+    onSelect: {
+      type: Function,
+      default: (item: any) => {}
+    }
+  },
+  components: { musicLIstItem },
+  data() {
+    return {
+      clientType: '',
+      idAndName: '',
+      pageInfo: {
+        // 分页规则
+        limit: 5, // 限制显示条数
+        page: 1, // 当前页
+        total: 0, // 总条数
+        page_size: [5, 10] // 选择限制显示条数
+      },
+      list: [] as any[],
+      loading: false,
+      dataShow: false // 是否有数据
+    }
+  },
+  mounted() {
+    const clientType = getUserType()
+    if (clientType === 'TEACHER') this.clientType = clientType
+    this.getList()
+  },
+  methods: {
+    onSearch() {
+      this.pageInfo.page = 1
+      this.list = []
+      this.dataShow = false
+      this.loading = false
+      this.getList()
+    },
+    async getList() {
+      this.loading = true
+      try {
+        const { data } = await request.post(
+          '/api-website/open/music/sheet/list',
+          {
+            data: {
+              idAndName: this.idAndName,
+              // subjectIds: this.subjectIds,
+              albumStatus: 'PASS',
+              page: this.pageInfo.page,
+              rows: this.pageInfo.limit,
+              state: 1
+            },
+            params: {
+              clientType: getUserType()
+            }
+          }
+        )
+        this.list = data.rows || []
+        this.pageInfo.total = data.total
+        if (data.total <= 0) {
+          this.dataShow = true
+        }
+      } catch {}
+      if (this.dataShow) {
+        this.loading = false
+      } else {
+        setTimeout(() => {
+          this.loading = false
+        }, 200)
+      }
+    }
+  },
+  render() {
+    return (
+      <>
+        <ElRow style={{ paddingBottom: '16px' }}>
+          <ElCol span={12}>
+            <ElInput
+              placeholder="请输入曲目名称"
+              clearable
+              size="large"
+              v-model={this.idAndName}
+            />
+          </ElCol>
+          <ElCol span={11} offset={1}>
+            <ElButton
+              type="primary"
+              size="large"
+              onClick={() => {
+                this.onSearch()
+              }}
+            >
+              搜索
+            </ElButton>
+          </ElCol>
+        </ElRow>
+        <div class="mt-2">
+          <ElSkeleton
+            loading={this.loading}
+            animated
+            class=" w-full m-auto px-[14px] flex items-center flex-col"
+            count={3}
+            v-slots={{
+              template: () => (
+                <div class="h-[94px] flex items-center justify-between w-full pt-2 mb-2">
+                  <div class="w-2/3 flex items-center">
+                    <ElSkeletonItem
+                      variant="circle"
+                      style={{ width: '88px', height: '88px' }}
+                    ></ElSkeletonItem>
+                    <div class="w-1/2 pl-2">
+                      <ElSkeletonItem variant="h3"></ElSkeletonItem>
+                      <ElSkeletonItem
+                        variant="p"
+                        style={{ width: '50%' }}
+                      ></ElSkeletonItem>
+                    </div>
+                  </div>
+                  <ElSkeletonItem
+                    variant="p"
+                    style={{ width: '20%' }}
+                  ></ElSkeletonItem>
+                </div>
+              )
+            }}
+          >
+            {this.list.map((item: any) => (
+              <musicLIstItem
+                item={item}
+                hiddenCollect={true}
+                isClick={true}
+                onClick={(item: any) => {
+                  this.onSelect({
+                    selectType: 'MUSIC',
+                    ...item
+                  })
+                }}
+              />
+            ))}
+          </ElSkeleton>
+        </div>
+
+        <Pagination
+          total={this.pageInfo.total}
+          v-model:page={this.pageInfo.page}
+          v-model:limit={this.pageInfo.limit}
+          pageSizes={this.pageInfo.page_size}
+          pagination={this.getList}
+        />
+
+        {this.dataShow && <ColEmpty style={{ marginBottom: '30px' }} />}
+      </>
+    )
+  }
+})

+ 16 - 0
vite.config.ts

@@ -37,6 +37,22 @@ export default defineConfig({
       scss: {
         charset: false
       }
+    },
+    postcss: {
+      plugins: [
+        {
+          postcssPlugin: 'internal:charset-removal',
+          AtRule: {
+            charset: atRule => {
+              if (atRule.name === 'charset') {
+                atRule.remove()
+              }
+            }
+          }
+        },
+        require('tailwindcss'),
+        require('autoprefixer')
+      ]
     }
   },
   resolve: {