Authored by qxm

动作下拉列表

@@ -52,5 +52,11 @@ export const MusclesApi = { @@ -52,5 +52,11 @@ export const MusclesApi = {
52 return await request.delete({ 52 return await request.delete({
53 url: `/motion/sub-categories/delete-list?ids=${ids.join(',')}` 53 url: `/motion/sub-categories/delete-list?ids=${ids.join(',')}`
54 }) 54 })
  55 + },
  56 + // 获取细分锻炼部位下拉列表
  57 + getsubCategoriesList: async () => {
  58 + return await request.get({
  59 + url: `/motion/sub-categories/simple-list`
  60 + })
55 } 61 }
56 } 62 }
@@ -95,5 +95,11 @@ export const MotionCategoryApi = { @@ -95,5 +95,11 @@ export const MotionCategoryApi = {
95 url: `/motion/categories/delete-list`, 95 url: `/motion/categories/delete-list`,
96 params: { ids } 96 params: { ids }
97 }) 97 })
  98 + },
  99 + // 获取部位/动作分类下拉列表
  100 + getCategoriesList: async () => {
  101 + return await request.get({
  102 + url: `/motion/categories/simple-list`
  103 + })
98 } 104 }
99 } 105 }
@@ -76,5 +76,11 @@ export const EquipmentsApi = { @@ -76,5 +76,11 @@ export const EquipmentsApi = {
76 params, 76 params,
77 responseType: 'blob' // 导出文件需指定响应类型 77 responseType: 'blob' // 导出文件需指定响应类型
78 }) 78 })
  79 + },
  80 + // 获取动作器械下拉列表
  81 + getEquipmentList: async () => {
  82 + return await request.get({
  83 + url: `/motion/equipments/simple-list`
  84 + })
79 } 85 }
80 } 86 }
1 <template> 1 <template>
2 <!-- 采用芋道全局封装的 Dialog 组件,内置滚动和自适应处理 --> 2 <!-- 采用芋道全局封装的 Dialog 组件,内置滚动和自适应处理 -->
3 <Dialog v-model="dialogVisible" :title="dialogTitle" width="800px"> 3 <Dialog v-model="dialogVisible" :title="dialogTitle" width="800px">
4 - <el-form  
5 - ref="formRef"  
6 - v-loading="formLoading"  
7 - :model="formData"  
8 - :rules="formRules"  
9 - label-width="120px"  
10 - > 4 + <el-form ref="formRef" v-loading="formLoading" :model="formData" :rules="formRules" label-width="120px">
11 <el-form-item label="动作名称" prop="name"> 5 <el-form-item label="动作名称" prop="name">
12 - <el-input  
13 - v-model="formData.name"  
14 - placeholder="请输入动作名称"  
15 - maxlength="50"  
16 - show-word-limit  
17 - /> 6 + <el-input v-model="formData.name" placeholder="请输入动作名称" maxlength="50" show-word-limit />
18 </el-form-item> 7 </el-form-item>
19 8
20 <el-form-item label="动作类型" prop="exerciseType"> 9 <el-form-item label="动作类型" prop="exerciseType">
@@ -31,12 +20,7 @@ @@ -31,12 +20,7 @@
31 20
32 <el-form-item label="部位分类" prop="categoryId"> 21 <el-form-item label="部位分类" prop="categoryId">
33 <el-select v-model="formData.categoryId" placeholder="请选择部位分类" class="w-full"> 22 <el-select v-model="formData.categoryId" placeholder="请选择部位分类" class="w-full">
34 - <el-option  
35 - v-for="item in categoryList"  
36 - :key="item.id"  
37 - :label="item.name"  
38 - :value="Number(item.id)"  
39 - /> 23 + <el-option v-for="item in categoryList" :key="item.id" :label="item.name" :value="Number(item.id)" />
40 </el-select> 24 </el-select>
41 </el-form-item> 25 </el-form-item>
42 26
@@ -47,24 +31,14 @@ @@ -47,24 +31,14 @@
47 </el-form-item> 31 </el-form-item>
48 32
49 <el-form-item label="主要训练部位" prop="primaryMuscles"> 33 <el-form-item label="主要训练部位" prop="primaryMuscles">
50 - <el-select  
51 - v-model="formData.primaryMuscles"  
52 - multiple  
53 - placeholder="请选择主要训练部位"  
54 - class="w-full"  
55 - >  
56 - <el-option v-for="item in muscleList" :key="item.id" :label="item.name" :value="item.id" /> 34 + <el-select v-model="formData.primaryMuscles" multiple placeholder="请选择主要训练部位" class="w-full">
  35 + <el-option v-for="item in primaryAvailableMuscles" :key="item.id" :label="item.name" :value="item.id" />
57 </el-select> 36 </el-select>
58 </el-form-item> 37 </el-form-item>
59 38
60 <el-form-item label="次要训练部位" prop="secondaryMuscles"> 39 <el-form-item label="次要训练部位" prop="secondaryMuscles">
61 - <el-select  
62 - v-model="formData.secondaryMuscles"  
63 - multiple  
64 - placeholder="请选择次要训练部位"  
65 - class="w-full"  
66 - >  
67 - <el-option v-for="item in muscleList" :key="item.id" :label="item.name" :value="item.id" /> 40 + <el-select v-model="formData.secondaryMuscles" multiple placeholder="请选择次要训练部位" class="w-full">
  41 + <el-option v-for="item in secondaryAvailableMuscles" :key="item.id" :label="item.name" :value="item.id" />
68 </el-select> 42 </el-select>
69 </el-form-item> 43 </el-form-item>
70 44
@@ -132,9 +106,21 @@ const formData = ref<any>({ @@ -132,9 +106,21 @@ const formData = ref<any>({
132 }) 106 })
133 107
134 // 基础下拉选项数据集 108 // 基础下拉选项数据集
135 -const muscleList = ref<any[]>([])  
136 -const categoryList = ref<any[]>([])  
137 -const toolList = ref<any[]>([]) 109 +const muscleList = ref<any[]>([])
  110 +const categoryList = ref<any[]>([])
  111 +const toolList = ref<any[]>([])
  112 +
  113 +// 可选主要训练部位:排除已选次要部位
  114 +const primaryAvailableMuscles = computed(() => {
  115 + const secondaryIds = new Set(formData.value.secondaryMuscles ?? [])
  116 + return muscleList.value.filter(item => !secondaryIds.has(item.id))
  117 +})
  118 +
  119 +// 可选次要训练部位:排除已选主要部位
  120 +const secondaryAvailableMuscles = computed(() => {
  121 + const primaryIds = new Set(formData.value.primaryMuscles ?? [])
  122 + return muscleList.value.filter(item => !primaryIds.has(item.id))
  123 +})
138 124
139 const formRules = reactive<FormRules>({ 125 const formRules = reactive<FormRules>({
140 name: [{ required: true, message: '请输入动作名称', trigger: 'blur' }], 126 name: [{ required: true, message: '请输入动作名称', trigger: 'blur' }],
@@ -164,16 +150,23 @@ const safeParseArray = (val: any): any[] => { @@ -164,16 +150,23 @@ const safeParseArray = (val: any): any[] => {
164 // 异步按需加载字典数据 150 // 异步按需加载字典数据
165 const loadOptions = async () => { 151 const loadOptions = async () => {
166 if (muscleList.value.length === 0) { 152 if (muscleList.value.length === 0) {
167 - const res = await MusclesApi.getMusclesPage({ pageNo: 1, pageSize: 100, name: '' })  
168 - muscleList.value = res.data?.list || res.list || [] 153 + const res = await MusclesApi.getsubCategoriesList()
  154 + muscleList.value = res || []
  155 + console.log('细分锻炼部位列表/肌肉res:', res);
  156 + console.log('muscleList 赋值后', muscleList.value)
  157 +
169 } 158 }
170 if (categoryList.value.length === 0) { 159 if (categoryList.value.length === 0) {
171 - const res = await MotionCategoryApi.getMotionCategoryPage({ pageNo: 1, pageSize: 100, name: '' })  
172 - categoryList.value = res.data?.list || res.list || [] 160 + const res = await MotionCategoryApi.getCategoriesList()
  161 + categoryList.value = res || []
  162 + console.log('部位列表res:', res);
  163 + console.log('categoryList 赋值后', categoryList.value)
173 } 164 }
174 if (toolList.value.length === 0) { 165 if (toolList.value.length === 0) {
175 - const res = await EquipmentsApi.getEquipmentsPage({ pageNo: 1, pageSize: 100, name: '' })  
176 - toolList.value = res.data?.list || res.list || [] 166 + const res = await EquipmentsApi.getEquipmentList()
  167 + toolList.value = res || []
  168 + console.log('器械列表res:', res);
  169 + console.log('categoryList 赋值后', categoryList.value)
177 } 170 }
178 } 171 }
179 172
@@ -192,7 +185,7 @@ const open = async (type: string, id?: number) => { @@ -192,7 +185,7 @@ const open = async (type: string, id?: number) => {
192 formLoading.value = true 185 formLoading.value = true
193 try { 186 try {
194 const data = await ExercisesApi.getExercises(id) 187 const data = await ExercisesApi.getExercises(id)
195 - console.log(data,"getExercises"); 188 + console.log(data, "getExercises");
196 // 处理回显:将后端保存的 String (如 "[1,2]") 格式化为 el-select 所需的 Array 189 // 处理回显:将后端保存的 String (如 "[1,2]") 格式化为 el-select 所需的 Array
197 data.primaryMuscles = safeParseArray(JSON.parse(data.primaryMuscles || '[]')) 190 data.primaryMuscles = safeParseArray(JSON.parse(data.primaryMuscles || '[]'))
198 data.secondaryMuscles = safeParseArray(JSON.parse(data.secondaryMuscles || '[]')) 191 data.secondaryMuscles = safeParseArray(JSON.parse(data.secondaryMuscles || '[]'))
@@ -245,8 +238,8 @@ const submitForm = async () => { @@ -245,8 +238,8 @@ const submitForm = async () => {
245 secondaryMuscles: JSON.stringify(formData.value.secondaryMuscles || []) 238 secondaryMuscles: JSON.stringify(formData.value.secondaryMuscles || [])
246 } 239 }
247 240
248 - console.log(submitData,"submitData");  
249 - 241 + console.log(submitData, "submitData");
  242 +
250 if (formType.value === 'create') { 243 if (formType.value === 'create') {
251 await ExercisesApi.addExercises(submitData) 244 await ExercisesApi.addExercises(submitData)
252 message.success('新增成功') 245 message.success('新增成功')