Browse Source

添加项目曲目

yuanliang 1 year ago
parent
commit
854d1f073a

+ 7 - 1
src/utils/constant.ts

@@ -257,7 +257,7 @@ export const appKey = {
   GYM: '管乐迷',
   GYT: '管乐团',
   KLX: '酷乐秀',
-  KT: '课堂乐器'
+  KT: '音乐数字课堂'
 } as any
 
 // 曲目收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)
@@ -271,4 +271,10 @@ export const musicSheetPaymentType = {
 export const musicSheetAvailableType = {
   ORG: '机构',
   PLATFORM: '平台',
+} as any
+
+// 曲目音频类型
+export const musicSheetAudioType = {
+  HOMEMODE: '自制伴奏',
+  COMMON: '普通伴奏',
 } as any

+ 12 - 0
src/views/music-library/api.ts

@@ -256,3 +256,15 @@ export const musicSheetApplicationExtendCategoryApplicationExtendInfo = (params?
     data: params
   } as any)
 }
+
+/**
+ *  @description: 查询分页(不同应用) 项目曲目
+ * @param params
+ */
+export const musicSheetPageByApplication = (params?: any) => {
+  return request({
+    url: '/cbs-app/musicSheet/pageByApplication',
+    method: 'post',
+    data: params
+  } as any)
+}

+ 2 - 2
src/views/music-library/music-sheet/component/music-list.tsx

@@ -2,7 +2,7 @@ import SaveForm from '@/components/save-form'
 import Pagination from '@/components/pagination'
 import {DataTableRowKey, NButton, NDataTable, NFormItem, NIcon, NImage, NInput, NModal, NSelect, NSpace, NTag, useDialog, useMessage} from 'naive-ui'
 import {defineComponent, onMounted, reactive, ref, watch} from 'vue'
-import {musicSheetCategoriesQueryTree, musicSheetDetail, musicSheetPage, musicSheetRemove, musicSheetStatusList, musicTagPage} from '../../api'
+import {musicSheetCategoriesQueryTree, musicSheetPage, musicSheetRemove, musicSheetStatusList, musicTagPage} from '../../api'
 import MusicOperation from '../modal/music-operation'
 import {subjectPage} from '@/views/system-manage/api'
 import MusicPreView from '../modal/musicPreView'
@@ -50,7 +50,7 @@ export default defineComponent({
       showUseProject: false, // 适用项目
       useProjectData: [], // 适用项目行数据
       showUseProjectId: null as any, // 适用项目行数据
-      detailReadonly: false // 新增、修改、详情是否可编辑
+      detailReadonly: false, // 新增、修改、详情是否可编辑
     })
 
     const columns = (): any => {

+ 59 - 40
src/views/music-library/project-music-sheet/index.tsx

@@ -1,62 +1,81 @@
-import { NTabPane, NTabs } from 'naive-ui'
-import { defineComponent, h, reactive, resolveDynamicComponent } from 'vue'
-import { useRoute } from 'vue-router'
-import { getTabsCache, setTabsCaches } from '@/hooks/use-async'
+import {NTabPane, NTabs} from 'naive-ui'
+import {defineComponent, onMounted, reactive} from 'vue'
+import {useRoute} from 'vue-router'
+import {setTabsCaches} from '@/hooks/use-async'
 import Mec from "@views/music-library/project-music-sheet/module/mec/mec";
 import Jmedu from "@views/music-library/project-music-sheet/module/jmedu/jmedu";
 import CooleshowEdu from "@views/music-library/project-music-sheet/module/cooleshow-edu/cooleshow-edu";
+import {appKey} from "@/utils/constant";
+import {sysApplicationPage} from "@views/menu-manage/api";
+
 export default defineComponent({
   name: 'project-music-sheet',
   setup() {
     const state = reactive({
-      tabName: 'mec' as 'mec' | 'jmedu' | 'cooleshow' | 'cooleshow-edu',
-      searchId: null
+      tabName: 'GYM' as 'GYM' | 'GYT' | 'KLX' | 'KT',
+      appKeyList: [] as any
     })
     const route = useRoute()
     const setTabs = (val: any) => {
       setTabsCaches(val, 'tabName', route)
     }
+
+    onMounted(async () => {
+      // 获取应用APP信息
+      {
+        const appKeys = Object.keys(appKey);
+        const {data} = await sysApplicationPage({page: 1, rows: 99, parentId: 0})
+        const tempList = data.rows || []
+        tempList.forEach((next: any) => {
+          if (appKeys.includes(next.appKey)) {
+            state.appKeyList.push(next.appKey)
+          }
+        })
+      }
+    })
+
+
     return () => {
       return (
-        <div class="system-menu-container">
-          <h2>项目曲目管理</h2>
+          <div class="system-menu-container">
+            <h2>项目曲目管理</h2>
 
-          <div class={['section-container']} style="padding-top: 0">
-            <NTabs
-              type="line"
-              size="large"
-              v-model:value={state.tabName}
-              onUpdate:value={(val: any) => setTabs(val)}
-            >
-              <NTabPane name="mec" tab="管乐迷"
-                  //v-auth="musicSheet/page1602301588206350338"
+            <div class={['section-container']} style="padding-top: 0">
+              <NTabs
+                  type="line"
+                  size="large"
+                  v-model:value={state.tabName}
+                  onUpdate:value={(val: any) => setTabs(val)}
               >
-                <Mec></Mec>
-              </NTabPane>
-              {/* <NTabPane name="TagList" tab="曲目标签管理" v-auth="musicTag/page1602301689389740033">
+                <NTabPane name="GYM" tab={appKey.GYM}
+                    //v-auth="musicSheet/page1602301588206350338"
+                >
+                  <Mec></Mec>
+                </NTabPane>
+                {/* <NTabPane name="TagList" tab="曲目标签管理" v-auth="musicTag/page1602301689389740033">
                 <TagList />
               </NTabPane> */}
-              <NTabPane
-                name="jmedu"
-                tab="管乐团"
-              >
-                <Jmedu></Jmedu>
-              </NTabPane>
-              <NTabPane
-                  name="cooleshow"
-                  tab="酷乐秀"
-              >
-                <Jmedu></Jmedu>
-              </NTabPane>
-              <NTabPane
-                  name="cooleshow-edu"
-                  tab="音乐数字课堂"
-              >
-                <CooleshowEdu></CooleshowEdu>
-              </NTabPane>
-            </NTabs>
+                <NTabPane
+                    name="GYT"
+                    tab={appKey.GYT}
+                >
+                  <Jmedu></Jmedu>
+                </NTabPane>
+                <NTabPane
+                    name="KLX"
+                    tab={appKey.KLX}
+                >
+                  <Jmedu></Jmedu>
+                </NTabPane>
+                <NTabPane
+                    name="KT"
+                    tab={appKey.KT}
+                >
+                  <CooleshowEdu></CooleshowEdu>
+                </NTabPane>
+              </NTabs>
+            </div>
           </div>
-        </div>
       )
     }
   }

+ 326 - 117
src/views/music-library/project-music-sheet/module/cooleshow-edu/addMusic.tsx

@@ -1,34 +1,96 @@
-import {defineComponent, onMounted, reactive, ref} from "vue";
+import {h, defineComponent, onMounted, reactive, ref} from "vue";
 import SaveForm from "@components/save-form";
-import {NButton, NDataTable, NDatePicker, NDescriptions, NDescriptionsItem, NFormItem, NImage, NInput, NModal, NSelect, NSpace, NStep, NSteps} from "naive-ui";
+import {
+  DataTableColumns,
+  DataTableRowKey,
+  NButton,
+  NCascader,
+  NDataTable,
+  NDescriptions,
+  NDescriptionsItem,
+  NFormItem,
+  NIcon,
+  NImage,
+  NInput,
+  NInputNumber,
+  NSelect,
+  NSpace,
+  NStep,
+  NSteps, useDialog
+} from "naive-ui";
 import Pagination from "@components/pagination";
-import TheTooltip from "@components/TheTooltip";
+import {getMapValueByKey, getSelectDataFromObj} from "@/utils/objectUtil";
+import {musicSheetSourceType, musicSheetType} from "@/utils/constant";
+import {musicSheetPage} from "@views/music-library/api";
+import deepClone from "@/utils/deep.clone";
+import {helpCenterCatalogRemove} from "@views/content-manage/api";
 
 export default defineComponent({
   name: 'project-music-sheet-mec',
+  props: {
+    appId: {
+      type: String,
+      required: true
+    },
+    subjectList: {
+      type: Array,
+      default: () => []
+    },
+    musicSheetCategories: {
+      type: Array,
+      default: () => []
+    }
+  },
   setup(props, {slots, attrs, emit}) {
+    const dialogs = useDialog()
     const state = reactive({
       loading: false,
       pagination: {
         page: 1,
-        rows: 10,
+        rows: 5,
+        pageTotal: 0
+      },
+      stepPagination: {
+        page: 1,
+        rows: 5,
         pageTotal: 0
       },
       searchForm: {
         keyword: null,
-        subjectType: null,
-        musicSubject: null,
-        status: null
+        musicSheetType: null,
+        subjectId: null,
+        sourceType: null,
       },
-      subjectList: [],
+      subjectList: [] as any,
       showAdd: false,
       currentStep: 1,
-      dataList: []
+      dataList: [],
+      selectRowData: [] as any,// 选择的数据列表
+      musicSheetCategories: [] as any,
+      startSortNum: null as any,// 排序起始值
     })
 
     onMounted(() => {
+      state.subjectList = props.subjectList
+      state.musicSheetCategories = props.musicSheetCategories
+      getList()
     })
 
+    const getList = async () => {
+      try {
+        state.loading = true
+        const {data} = await musicSheetPage({
+          ...state.pagination,
+          ...state.searchForm,
+          addAppId: props.appId
+        })
+        state.pagination.pageTotal = Number(data.total)
+        state.dataList = data.rows || []
+      } catch {
+      }
+      state.loading = false
+    }
+
     const saveForm = ref()
 
     const onSearch = () => {
@@ -39,108 +101,231 @@ export default defineComponent({
     }
 
     const onSubmit = () => {
-
+      state.pagination.page = 1
+      getList()
     }
 
+    const columnsField = [
+      {
+        type: 'selection'
+      },
+      {
+        title: '曲目编号',
+        key: 'id',
+      },
+      {
+        title: '封面图',
+        key: 'titleImg',
+        render(row: any) {
+          return <NImage width={40} height={40} src={row.musicCover}/>
+        }
+      },
+      {
+        title: '声部',
+        key: 'subjectNames',
+      },
+      {
+        title: '曲目名称',
+        key: 'name',
+      },
+      {
+        title: '音乐人',
+        key: 'composer',
+      },
+      {
+        title: '曲目类型',
+        key: 'musicSheetType',
+        render: (row: any) => {
+          return <div>{getMapValueByKey(row.musicSheetType, new Map(Object.entries(musicSheetType)))}</div>
+        }
+      },
+      {
+        title: '作者属性',
+        key: 'sourceType',
+        render(row: any) {
+          return getMapValueByKey(row.sourceType, new Map(Object.entries(musicSheetSourceType)));
+        }
+      },
+      {
+        title: '所属人',
+        key: 'userName',
+        render: (row: any) => {
+          return <div>{row.musicSheetExtend?.userName ? row.musicSheetExtend?.userName : ''}</div>
+        }
+      },
+    ]
+
     const columns = (): any => {
-      return [
-        {
-          title: '曲目信息',
-          key: 'id',
-          render: (row: any) => (
-              <>
-                <NDescriptions labelPlacement="left" column={1}>
-                  <NDescriptionsItem label="曲目名称">
-                    <TheTooltip content={row.musicSheetName}/>{' '}
-                  </NDescriptionsItem>
-                  <NDescriptionsItem label="曲目编号">{row.id}</NDescriptionsItem>
-                </NDescriptions>
-              </>
+      return columnsField
+    }
+
+    const stepColumns = (): DataTableColumns => {
+      const field = deepClone(columnsField);
+      field.splice(0, 1)
+      field.push({
+        title: '曲目分类',
+        key: 'projectMusicCategoryId',
+        fixed: 'right',
+        width: 200,
+        render: (row: any) => {
+          // })
+          return (
+              <NCascader
+                  valueField="id"
+                  labelField="name"
+                  children-field="children"
+                  placeholder="请选择曲目分类"
+                  value={row.projectMusicCategoryId}
+                  options={state.musicSheetCategories}
+                  onUpdateValue={(value: any) => {
+                    row.projectMusicCategoryId = value
+                  }}
+                  clearable
+              />
           )
+        }
+      })
+      field.push({
+        title(column: any) {
+          return (
+              <NSpace>
+                排序
+                <NButton type="primary"
+                         size="small"
+                         text
+                         onClick={() => {
+                           dialogs.create({
+                             title: "请输入排序起始值",
+                             showIcon: false,
+                             content: () => {
+                               return h(
+                                   "div",
+                                   {
+                                     class: "flex flex-col justify-center items-center text-14px",
+                                   },
+                                   [
+                                     // icon
+                                     h(NInputNumber, {
+                                       onUpdateValue(v) {
+                                         state.startSortNum = v
+                                       }
+                                     }),
+                                   ]
+                               )
+                             },
+                             positiveText: "确定",
+                             negativeText: '取消',
+                             onPositiveClick: () => {
+                               if (state.startSortNum) {
+                                 for (let i = 0; i < state.selectRowData.length; i++) {
+                                   const item = state.selectRowData[i];
+                                   item.sortNo = state.startSortNum + i
+                                 }
+                               }
+                             },
+                           })
+                         }
+                         }
+                >
+                  <NIcon size={15} style="padding-left: 9px">
+                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+                      <path d="M2 26h28v2H2z" fill="currentColor"></path>
+                      <path 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" fill="currentColor"></path>
+                    </svg>
+                  </NIcon>
+                </NButton>
+              </NSpace>
+          )
+
         },
-        {
-          title: '封面图',
-          key: 'titleImg',
-          render(row: any) {
-            return <NImage width={60} height={60} src={row.titleImg}/>
-          }
-        },
-        {
-          title: '声部',
-          key: 'titleImg',
-        },
-        {
-          title: '曲目名称',
-          key: 'titleImg',
-        },
-        {
-          title: '音乐人',
-          key: 'titleImg',
-        },
-        {
-          title: '曲目类型',
-          key: 'titleImg',
-        },
-        {
-          title: '作者属性',
-          key: 'titleImg',
-        },
-        {
-          title: '所属人',
-          key: 'titleImg',
-        },
-        {
-          title: '操作',
-          key: 'operation',
-          fixed: 'right',
-          render(row: any) {
-            return (
-                <NSpace>
-                  <NButton
-                      type="primary"
-                      size="small"
-                      text
-                      //v-auth="musicSheet/status1612431726029942786"
-                      // onClick={() => onChangeStatus(row)}
-                  >
-                    {row.status ? '停用' : '启用'}
-                  </NButton>
-                  <NButton
-                      type="primary"
-                      size="small"
-                      text
-                      //v-auth="musicSheet/update1602302618558099458"
-                      onClick={() => {
-                        // state.visiableMusic = true
-                        // state.musicOperation = 'edit'
-                        // state.musicData = row
-                      }}
-                  >
-                    修改
-                  </NButton>
-                </NSpace>
-            )
-          }
+        key: 'sortNo',
+        fixed: 'right',
+        width: 150,
+        render: (row: any) => {
+          return h(NInputNumber, {
+            value: row.sortNo,
+            onUpdateValue(value: any) {
+              row.sortNo = value
+              console.log(state.selectRowData)
+            }
+          })
         }
-      ]
+      })
+      field.push({
+        title: '操作',
+        key: 'operation',
+        fixed: 'right',
+        render(row: any) {
+          return (
+              <NSpace>
+                <NButton
+                    type="primary"
+                    size="small"
+                    text
+                    //v-auth="musicSheet/update1602302618558099458"
+                    onClick={() => {
+                      dialogs.warning({
+                        title: '警告',
+                        content: `是否删除该数据?`,
+                        positiveText: '确定',
+                        negativeText: '取消',
+                        onPositiveClick: async () => {
+                          try {
+                            const index = state.selectRowData.findIndex((item: any) => {
+                              if (item.id == row.id) {
+                                return true
+                              }
+                            })
+                            if (index > -1) {
+                              state.selectRowData.splice(index, 1)
+                            }
+                          } catch {
+                          }
+                        }
+                      })
+                    }}
+                >
+                  移除
+                </NButton>
+              </NSpace>
+          )
+        }
+      })
+      return field;
     }
 
     const updateCurrent = (val: any) => {
       state.currentStep = val
     }
 
+    const checkedRowKeysRef = ref<DataTableRowKey[]>([])
+    const handleCheck = (rowKeys: DataTableRowKey[]) => {
+      checkedRowKeysRef.value = rowKeys
+      // 添加行更新值
+      state.dataList.forEach((next: any) => {
+        if (checkedRowKeysRef.value.includes(next.id)) {
+          const find = state.selectRowData.find((row: any) => {
+            return row.id === next.id
+          });
+          if (!find) {
+            state.selectRowData.push(next)
+          }
+        }
+      })
+
+      // 去掉行更新值
+      state.selectRowData = state.selectRowData.filter((next: any) => {
+        return checkedRowKeysRef.value.includes(next.id)
+      })
+    }
+
     return () => {
       return (
           <div class="system-menu-container">
             <NSpace vertical size="medium">
-              <NSteps current={state.currentStep} onUpdateCurrent={updateCurrent} style={"margin-bottom: 20px;"}>
-                <NStep
-                    title="选择分类"
-                    description=""
-                >
-                </NStep>
+              <NSteps current={state.currentStep} onUpdateCurrent={updateCurrent} style={"margin-bottom: 10px;margin-top: 10px"}>
                 <NStep
-                    title="选择分类下曲目"
+                    title="选择曲目"
                     description=""
                 >
                 </NStep>
@@ -152,26 +337,46 @@ export default defineComponent({
               </NSteps>
             </NSpace>
             {state.currentStep === 1 && (
-                <SaveForm>
-                  <NFormItem label="关键词" path="keyword">
-                    <NSelect></NSelect>
-                  </NFormItem>
-                </SaveForm>
-            )}
-            {state.currentStep === 2 && (
                 <div class="system-menu-container">
-                  <SaveForm>
+                  <SaveForm
+                      ref={saveForm}
+                      model={state.searchForm}
+                      onSubmit={onSubmit}
+                      // saveKey="cooleshow-edu-addMusic"
+                      onSetModel={(val: any) => (state.searchForm = val)}
+                  >
                     <NFormItem label="关键词" path="keyword">
-                      <NSelect></NSelect>
+                      <NInput
+                          v-model:value={state.searchForm.keyword}
+                          placeholder="请输入曲目名称/编号"
+                          clearable
+                      />
                     </NFormItem>
-                    <NFormItem label="曲目类型" path="keyword">
-                      <NSelect></NSelect>
+                    <NFormItem label="曲目类型" path="musicSheetType">
+                      <NSelect
+                          placeholder="请选择曲目类型"
+                          v-model:value={state.searchForm.musicSheetType}
+                          options={getSelectDataFromObj(musicSheetType)}
+                          clearable
+                      />
                     </NFormItem>
-                    <NFormItem label="声部" path="keyword">
-                      <NSelect></NSelect>
+                    <NFormItem label="声部" path="musicSubject">
+                      <NSelect
+                          placeholder="请选择声部"
+                          v-model:value={state.searchForm.subjectId}
+                          options={state.subjectList}
+                          clearable
+                      />
                     </NFormItem>
-                    <NFormItem label="曲目来源" path="keyword">
-                      <NSelect></NSelect>
+                    <NFormItem label="曲目来源" path="sourceType">
+                      <NSelect
+                          placeholder="请选择曲目来源"
+                          v-model:value={state.searchForm.sourceType}
+                          options={getSelectDataFromObj(musicSheetSourceType)}
+                          // onUpdateValue={async (value: any) => {
+                          // }}
+                          clearable
+                      />
                     </NFormItem>
                     <NFormItem>
                       <NSpace>
@@ -188,27 +393,31 @@ export default defineComponent({
                       loading={state.loading}
                       columns={columns()}
                       data={state.dataList}
+                      rowKey={(row: any) => row.id}
+                      onUpdateCheckedRowKeys={handleCheck}
                   ></NDataTable>
                   <Pagination
                       v-model:page={state.pagination.page}
                       v-model:pageSize={state.pagination.rows}
                       v-model:pageTotal={state.pagination.pageTotal}
-                      // onList={getList}
+                      onList={getList}
                       sync
-                      saveKey="music-list"
+                      // saveKey="cooleshow-edu-addMusic"
                   ></Pagination>
                 </div>
             )}
-            {state.currentStep === 3 && (
+            {state.currentStep === 2 && (
                 <div class="system-menu-container" style={"margin-top: 15px;"}>
                   <NDataTable
                       loading={state.loading}
-                      columns={columns()}
-                      data={state.dataList}
+                      columns={stepColumns()}
+                      data={state.selectRowData}
+                      rowKey={(row: any) => row.id}
+                      maxHeight={500}
                   ></NDataTable>
                 </div>
             )}
-            <NSpace justify="end">
+            <NSpace justify="end" style={"margin-top:10px"}>
               <NButton type="default" onClick={() => {
                 if (state.currentStep > 1) {
                   state.currentStep = state.currentStep - 1;
@@ -221,7 +430,7 @@ export default defineComponent({
               <NButton
                   type="primary"
                   onClick={() => {
-                    if (state.currentStep < 3) {
+                    if (state.currentStep < 2) {
                       state.currentStep = state.currentStep + 1;
                     } else {
                       onSubmit()
@@ -230,7 +439,7 @@ export default defineComponent({
                   // loading={btnLoading.value}
                   // disabled={btnLoading.value}
               >
-                {state.currentStep === 3 ? '确定' : '下一步'}
+                {state.currentStep === 2 ? '确定' : '下一步'}
               </NButton>
             </NSpace>
           </div>

+ 256 - 106
src/views/music-library/project-music-sheet/module/cooleshow-edu/cooleshow-edu.tsx

@@ -1,16 +1,26 @@
 import {defineComponent, onMounted, reactive, ref} from "vue";
 import SaveForm from "@components/save-form";
-import {NButton, NDataTable, NDatePicker, NDescriptions, NDescriptionsItem, NFormItem, NImage, NInput, NModal, NSelect, NSpace} from "naive-ui";
+import {DataTableRowKey, NButton, NCascader, NDataTable, NDatePicker, NDescriptions, NDescriptionsItem, NFormItem, NInput, NModal, NSelect, NSpace, NTag, useDialog, useMessage} from "naive-ui";
 import Pagination from "@components/pagination";
 import TheTooltip from "@components/TheTooltip";
-import AddMusic from "@views/music-library/project-music-sheet/module/jmedu/addMusic";
+import AddMusic from "@views/music-library/project-music-sheet/module/cooleshow-edu/addMusic";
+import {musicSheetApplicationExtendCategoryList, musicSheetApplicationOwnerList, musicSheetPageByApplication, musicSheetStatusList} from "@views/music-library/api";
+import {getMapValueByKey, getSelectDataFromObj} from "@/utils/objectUtil";
+import {musicSheetAudioType, musicSheetAvailableType, musicSheetPaymentType, musicSheetSourceType, musicSheetType} from "@/utils/constant";
+import {sysApplicationPage} from "@views/menu-manage/api";
+import {subjectPage} from "@views/system-manage/api";
+import {filterTimes} from "@/utils/dateUtil";
 
 export default defineComponent({
   name: 'project-music-sheet-jmedu',
 
   setup() {
+    const dialog = useDialog()
+    const message = useMessage()
     const state = reactive({
       loading: false,
+      appKey: 'KT',
+      appId: null as any,
       pagination: {
         page: 1,
         rows: 10,
@@ -18,15 +28,76 @@ export default defineComponent({
       },
       searchForm: {
         keyword: null,
-        subjectType: null,
-        musicSubject: null,
-        status: null
+        applicationId: null, //应用ID
+        musicSheetType: null, //曲目类型(SINGLE:单曲 CONCERT:合奏)
+        subjectId: null, //声部ID
+        subjectIds: null, //曲目声部ID集合
+        musicCategoryIds: null, //曲目分类ID
+        status: null, //曲目状态(0:停用,1:启用)
+        sourceType: null, //来源类型/作者属性(PLATFORM: 平台; ORG: 机构; PERSON: 个人)
+        paymentType: null, //收费类型(FREE:免费;VIP:会员;CHARGE:单曲收费)
+        userId: null, //所属人
+        musicCategoryId: null, //曲目分类ID
+        times: null, // 上传时间
+        // startTime: null, //上传时间(年月日)
+        // endTime: null, //上传时间(年月日)
+        audioType: null, //音频类型(HOMEMODE: 自制 COMMON: 普通)
+        exquisiteFlag: null, //精品标志
+        topFlag: null, //是否置顶(0:否;1:是)
+        availableType: null, //可用途径 ORG 机构 PLATFORM 平台
+        appAuditFlag: null, //是否审核版本
+        detailFlag: null, //是否查询详情
       },
       subjectList: [],
-      showAdd: false
+      showAdd: false,
+      dataList: [] as any[],
+      musicSheetCategories: [],
+      showAddDialog: false,
+      showEditDialog: false,
+      userIdDisable: true,
+      userIdData: [] as any,
     })
 
-    onMounted(() => {
+    onMounted(async () => {
+
+      // 获取应用APP信息
+      {
+        const {data} = await sysApplicationPage({page: 1, rows: 1, appKey: state.appKey})
+        const tempList = data.rows || []
+        if (!tempList || tempList.length == 0) {
+          message.error("加载项目信息失败");
+          return
+        }
+        state.appId = tempList[0].id
+        state.searchForm.applicationId = tempList[0].id
+      }
+
+      // 加载声部
+      {
+        try {
+          const {data} = await subjectPage({page: 1, rows: 999})
+          const tempList = data.rows || []
+          tempList.forEach((item: any) => {
+            item.label = item.name
+            item.value = item.id + ''
+          })
+          state.subjectList = tempList
+        } catch {
+        }
+      }
+
+      //加载曲目分类列表
+      {
+        const {data} = await musicSheetApplicationExtendCategoryList({applicationIds: state.appId})
+        if (data && data.length > 0) {
+          state.musicSheetCategories = data[0].musicSheetCategories
+        }
+      }
+
+      // 加载表格数据
+      {
+        getList()
+      }
     })
 
     const saveForm = ref()
@@ -39,19 +110,90 @@ export default defineComponent({
     }
 
     const onSubmit = () => {
+      state.pagination.page = 1
+      getList()
+    }
 
+    const checkedRowKeysRef = ref<DataTableRowKey[]>([])
+    const handleCheck = (rowKeys: DataTableRowKey[]) => {
+      checkedRowKeysRef.value = rowKeys
+    }
+
+    const getList = async () => {
+      try {
+        state.loading = true
+        const {data} = await musicSheetPageByApplication({
+          ...state.pagination,
+          ...state.searchForm,
+          ...filterTimes(state.searchForm.times, ['startTime', 'endTime']),
+        })
+        state.pagination.pageTotal = Number(data.total)
+        state.dataList = data.rows || []
+      } catch {
+      }
+      state.loading = false
+    }
+
+    const onChangeStatus = (row: any) => {
+      const statusStr = row.status ? '停用' : '启用'
+      dialog.warning({
+        title: '警告',
+        content: `是否${statusStr}?`,
+        positiveText: '确定',
+        negativeText: '取消',
+        onPositiveClick: async () => {
+          try {
+            await musicSheetStatusList({
+              ids: new Array(row.id),
+              status: !row.status
+            })
+            getList()
+            message.success(`${statusStr}成功`)
+          } catch {
+          }
+        }
+      })
+    }
+
+
+    const onBatchChangeStatus = (status: boolean) => {
+      const length = checkedRowKeysRef.value.length;
+      if (length == 0) {
+        message.warning("未选择数据")
+      }
+      const statusStr = !status ? '停用' : '启用'
+      dialog.warning({
+        title: '警告',
+        content: `是否${statusStr}` + length + `条数据?`,
+        positiveText: '确定',
+        negativeText: '取消',
+        onPositiveClick: async () => {
+          try {
+            await musicSheetStatusList({
+              ids: checkedRowKeysRef.value,
+              status: status
+            })
+            getList()
+            message.success(`${statusStr}成功`)
+          } catch {
+          }
+        }
+      })
     }
 
     const columns = (): any => {
       return [
         {
+          type: 'selection'
+        },
+        {
           title: '曲目信息',
           key: 'id',
           render: (row: any) => (
               <>
                 <NDescriptions labelPlacement="left" column={1}>
                   <NDescriptionsItem label="曲目名称">
-                    <TheTooltip content={row.musicSheetName}/>{' '}
+                    <TheTooltip content={row.name}/>{' '}
                   </NDescriptionsItem>
                   <NDescriptionsItem label="曲目编号">{row.id}</NDescriptionsItem>
                 </NDescriptions>
@@ -59,55 +201,57 @@ export default defineComponent({
           )
         },
         {
-          title: '封面图',
-          key: 'titleImg',
-          render(row: any) {
-            return <NImage width={60} height={60} src={row.titleImg}/>
-          }
-        },
-        {
           title: '曲目来源',
           key: 'musicSheetCategoriesName',
           render: (row: any) => (
               <>
                 <NDescriptions labelPlacement="left" column={1}>
                   <NDescriptionsItem label="曲目来源">
-                    <TheTooltip content={row.musicSheetCategoriesName}/>{' '}
-                  </NDescriptionsItem>
-                  <NDescriptionsItem label="所属人">
-                    {row.accompanimentType === 'HOMEMODE' ? '自制伴奏' : '普通伴奏'}
+                    {getMapValueByKey(row.sourceType, new Map(Object.entries(musicSheetSourceType)))}
                   </NDescriptionsItem>
+                  <NDescriptionsItem label="所属人">{row.userName}</NDescriptionsItem>
                 </NDescriptions>
               </>
           )
         },
         {
           title: '曲目类型',
-          key: 'musicSheetCategoriesName'
+          key: 'musicSheetType',
+          render: (row: any) => {
+            return <div>{getMapValueByKey(row.musicSheetType, new Map(Object.entries(musicSheetType)))}</div>
+          }
         },
         {
           title: '可用声部',
-          key: 'musicSheetCategoriesName'
+          key: 'subjectIdNames'
         },
         {
           title: '分类',
-          key: 'musicSheetCategoriesName'
+          key: 'musicSheetCategoryName'
         },
         {
           title: '是否收费',
-          key: 'musicSheetCategoriesName'
+          key: 'paymentType',
+          render: (row: any) => {
+            return <div>{getMapValueByKey(row.paymentType, new Map(Object.entries(musicSheetPaymentType)))}</div>
+          }
         },
         {
           title: '上传人',
-          key: 'musicSheetCategoriesName'
+          key: 'userId'
         },
         {
           title: '上传时间',
-          key: 'musicSheetCategoriesName'
+          key: 'createTime'
         },
         {
           title: '状态',
-          key: 'musicSheetCategoriesName'
+          key: 'status',
+          render(row: any) {
+            return (
+                <NTag type={row.status ? 'primary' : 'default'}>{row.status ? '启用' : '停用'}</NTag>
+            )
+          }
         },
         {
           title: '操作',
@@ -121,7 +265,7 @@ export default defineComponent({
                       size="small"
                       text
                       //v-auth="musicSheet/status1612431726029942786"
-                      // onClick={() => onChangeStatus(row)}
+                      onClick={() => onChangeStatus(row)}
                   >
                     {row.status ? '停用' : '启用'}
                   </NButton>
@@ -131,9 +275,7 @@ export default defineComponent({
                       text
                       //v-auth="musicSheet/update1602302618558099458"
                       onClick={() => {
-                        // state.visiableMusic = true
-                        // state.musicOperation = 'edit'
-                        // state.musicData = row
+                        state.showEditDialog = true
                       }}
                   >
                     修改
@@ -152,54 +294,89 @@ export default defineComponent({
                 ref={saveForm}
                 model={state.searchForm}
                 onSubmit={onSubmit}
-                saveKey="music-list"
+                saveKey="cooleshow-edu"
                 onSetModel={(val: any) => (state.searchForm = val)}
             >
 
               <NFormItem label="关键词" path="keyword">
                 <NInput
-                    placeholder="曲目名称/编号"
+                    placeholder="请输入曲目名称/编号"
                     v-model:value={state.searchForm.keyword}
                     clearable
                 />
               </NFormItem>
-
+              <NFormItem label="分类" path="musicCategoryId">
+                <NCascader
+                    valueField="id"
+                    labelField="name"
+                    children-field="children"
+                    placeholder="请选择分类"
+                    v-model:value={state.searchForm.musicCategoryId}
+                    options={state.musicSheetCategories}
+                    clearable
+                />
+              </NFormItem>
+              <NFormItem
+                  label="可用途径"
+                  path="availableType"
+              >
+                <NSelect
+                    placeholder="请选择可用途径"
+                    v-model:value={state.searchForm.availableType}
+                    options={getSelectDataFromObj(musicSheetAvailableType)}
+                    clearable
+                >
+                </NSelect>
+              </NFormItem>
               <NFormItem label="曲目类型" path="subjectType">
                 <NSelect
                     placeholder="请选择曲目类型"
-                    v-model:value={state.searchForm.subjectType}
-                    options={
-                      [
-                        {
-                          label: '独奏',
-                          value: '1'
-                        },
-                        {
-                          label: '合奏',
-                          value: '2'
-                        }
-                      ]
-                    }
+                    v-model:value={state.searchForm.musicSheetType}
+                    options={getSelectDataFromObj(musicSheetType)}
                     clearable
                 />
               </NFormItem>
-              <NFormItem label="伴奏类型" path="musicSubject">
+              <NFormItem label="曲目来源" path="sourceType">
                 <NSelect
+                    placeholder="请选择曲目来源"
+                    v-model:value={state.searchForm.sourceType}
+                    options={getSelectDataFromObj(musicSheetSourceType)}
+                    onUpdateValue={async (value: any) => {
+                      console.log(value)
+                      state.userIdData = []
+                      state.searchForm.userId = null
+                      if (value) {
+                        const {data} = await musicSheetApplicationOwnerList({page: 1, rows: 9999, sourceType: value, applicationId: state.appId})
+                        const temp = data.rows || []
+                        temp.forEach((next: any) => {
+                          state.userIdData.push({
+                            ...next,
+                            label: next.userName,
+                            value: next.userId
+                          })
+                        })
+                        state.userIdDisable = false
+                      } else {
+                        state.userIdDisable = true
+                      }
+                    }}
+                    clearable
                 />
               </NFormItem>
-              <NFormItem label="声部" path="musicSubject">
+              <NFormItem label="所属人" path="userId">
                 <NSelect
-                    placeholder="请选择声部"
-                    v-model:value={state.searchForm.musicSubject}
-                    options={state.subjectList}
+                    placeholder="请选择所属人"
+                    disabled={state.userIdDisable}
+                    v-model:value={state.searchForm.userId}
+                    options={state.userIdData}
                     clearable
-                />
+                >
+                </NSelect>
               </NFormItem>
               <NFormItem label="状态" path="status">
                 <NSelect
-                    v-model={[state.searchForm.status, 'value']}
+                    v-model:value={state.searchForm.status}
                     placeholder="请选择状态"
-                    clearable
                     options={
                       [
                         {
@@ -212,61 +389,28 @@ export default defineComponent({
                         }
                       ] as any
                     }
+                    clearable
                 />
               </NFormItem>
-              <NFormItem label="曲目来源" path="authorFrom">
+              <NFormItem label="声部" path="subjectId">
                 <NSelect
-                    placeholder="请选择曲目来源"
-                    // v-model:value={state.searchForm.authorFrom}
-                    options={
-                      [
-                        {
-                          label: '平台',
-                          value: 'PLATFORM'
-                        },
-                        {
-                          label: '机构',
-                          value: 'TENANT'
-                        },
-                        {
-                          label: '个人',
-                          value: 'SELF'
-                        }
-                      ] as any
-                    }
+                    placeholder="请选择声部"
+                    v-model:value={state.searchForm.subjectId}
+                    options={state.subjectList}
                     clearable
                 />
               </NFormItem>
-
-              <NFormItem label="曲目类型" path="authorFrom">
+              <NFormItem label="伴奏类型" path="audioType">
                 <NSelect
-                    placeholder="请选择收费类型"
-                    // v-model:value={state.searchForm.authorFrom}
-                    options={
-                      [
-                        {
-                          label: '独奏',
-                          value: 'PLATFORM'
-                        },
-                        {
-                          label: '合奏',
-                          value: 'TENANT'
-                        }
-                      ] as any
-                    }
+                    placeholder="请选择伴奏类型"
+                    v-model:value={state.searchForm.audioType}
+                    options={getSelectDataFromObj(musicSheetAudioType)}
                     clearable
                 />
               </NFormItem>
-
-              <NFormItem label="所属人" path="authorFrom">
-                <NInput></NInput>
-              </NFormItem>
-              <NFormItem label="曲目分类" path="authorFrom">
-                <NSelect></NSelect>
-              </NFormItem>
               <NFormItem label="上传时间" path="authorFrom">
                 <NDatePicker
-                    // v-model:value={state.searchForm.times}
+                    v-model:value={state.searchForm.times}
                     type="daterange"
                     clearable
                     value-format="yyyy.MM.dd"
@@ -298,19 +442,19 @@ export default defineComponent({
                   新增
                 </NButton>
                 <NButton
+                    disabled={checkedRowKeysRef.value.length == 0}
                     //v-auth="musicSheet/save1602302550719426561"
                     onClick={() => {
-                      // state.musicOperation = 'unable'
-                      // state.musicData = {}
+                      onBatchChangeStatus(false)
                     }}
                 >
                   批量禁用
                 </NButton>
                 <NButton
+                    disabled={checkedRowKeysRef.value.length == 0}
                     //v-auth="musicSheet/save1602302550719426561"
                     onClick={() => {
-                      // state.musicOperation = 'enable'
-                      // state.musicData = {}
+                      onBatchChangeStatus(true)
                     }}
                 >
                   批量启用
@@ -320,16 +464,18 @@ export default defineComponent({
               <NDataTable
                   loading={state.loading}
                   columns={columns()}
-                  // data={state.dataList}
+                  data={state.dataList}
+                  rowKey={(row: any) => row.id}
+                  onUpdateCheckedRowKeys={handleCheck}
               ></NDataTable>
 
               <Pagination
                   v-model:page={state.pagination.page}
                   v-model:pageSize={state.pagination.rows}
                   v-model:pageTotal={state.pagination.pageTotal}
-                  // onList={getList}
+                  onList={getList}
                   sync
-                  saveKey="music-list"
+                  saveKey="cooleshow-edu"
               ></Pagination>
             </div>
 
@@ -338,9 +484,13 @@ export default defineComponent({
                 preset="dialog"
                 showIcon={false}
                 title={'添加曲目'}
-                style={{width: '1200px',height: '800px'}}
+                style={{width: '1200px'}}
             >
-              <AddMusic/>
+              <AddMusic
+                  subjectList={state.subjectList}
+                  appId={state.appId}
+                  musicSheetCategories={state.musicSheetCategories}
+              />
             </NModal>
           </div>
       )