🎈 perf(产业运营平台-电商交易模块的页面中筛选条件存在的问题优化,替换新组件;增加三级tabs切换通用组件;):
This commit is contained in:
		
							parent
							
								
									ec47e147dc
								
							
						
					
					
						commit
						30470ee192
					
				
							
								
								
									
										1
									
								
								sub-operation-service/components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								sub-operation-service/components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -14,6 +14,7 @@ declare module 'vue' { | |||||||
|     CodeDialog: typeof import('./src/components/code-dialog/index.vue')['default'] |     CodeDialog: typeof import('./src/components/code-dialog/index.vue')['default'] | ||||||
|     copy: typeof import('./src/components/custom-scroll-title copy/index.vue')['default'] |     copy: typeof import('./src/components/custom-scroll-title copy/index.vue')['default'] | ||||||
|     CostomImg: typeof import('./src/components/costomImg.vue')['default'] |     CostomImg: typeof import('./src/components/costomImg.vue')['default'] | ||||||
|  |     CostomTabs: typeof import('./src/components/costomTabs.vue')['default'] | ||||||
|     CustomBack: typeof import('./src/components/customBack.vue')['default'] |     CustomBack: typeof import('./src/components/customBack.vue')['default'] | ||||||
|     CustomCarouselPicture: typeof import('./src/components/custom-carousel-picture/index.vue')['default'] |     CustomCarouselPicture: typeof import('./src/components/custom-carousel-picture/index.vue')['default'] | ||||||
|     CustomEchartBar: typeof import('./src/components/custom-echart-bar/index.vue')['default'] |     CustomEchartBar: typeof import('./src/components/custom-echart-bar/index.vue')['default'] | ||||||
|  | |||||||
							
								
								
									
										469
									
								
								sub-operation-service/src/components/costomTabs.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										469
									
								
								sub-operation-service/src/components/costomTabs.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,469 @@ | |||||||
|  | <template> | ||||||
|  |   <!-- tabs少数据时用这个,多数据时单行会两端有切换箭头 --> | ||||||
|  |   <!-- <div class="coustom-tabs-container" :style="{ fontSize: props.fontSize }"> | ||||||
|  |     <el-tabs v-model="active1Current" @tab-change="handle1Click"> | ||||||
|  |       <el-tab-pane v-for="item in tabsLivel1Data" :key="item.id" :label="item.name" :name="item.id"> </el-tab-pane> | ||||||
|  |     </el-tabs> | ||||||
|  |     <el-tabs v-show="showLivel >= 2 && tabsLivel2Data.length > 0" v-model="active2Current" @tab-change="handle2Click"> | ||||||
|  |       <el-tab-pane v-for="item in tabsLivel2Data" :key="item.id" :label="item.name" :name="item.id"> </el-tab-pane> | ||||||
|  |     </el-tabs> | ||||||
|  |     <el-tabs v-show="showLivel >= 3 && tabsLivel3Data.length > 0" v-model="active3Current" @tab-change="handle3Click"> | ||||||
|  |       <el-tab-pane v-for="item in tabsLivel3Data" :key="item.id" :label="item.name" :name="item.id"> </el-tab-pane> | ||||||
|  |     </el-tabs> | ||||||
|  |   </div> --> | ||||||
|  | 
 | ||||||
|  |   <!-- 自定义选项卡样式 --> | ||||||
|  |   <div class="coustom-div-container" :style="{ fontSize: props.fontSize }"> | ||||||
|  |     <!-- 第一级选项卡 - 改为使用 div 模拟 --> | ||||||
|  |     <div class="custom-tabs-container"> | ||||||
|  |       <div | ||||||
|  |         v-for="item in tabsLivel1Data" | ||||||
|  |         :key="item.id" | ||||||
|  |         class="custom-tab-item" | ||||||
|  |         :class="{ | ||||||
|  |           active: active1Current === item.id, | ||||||
|  |           'all-tab': item.isAll, | ||||||
|  |         }" | ||||||
|  |         @click="handleCustomTabClick(1, item)" | ||||||
|  |       > | ||||||
|  |         {{ item.name }} | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |     <!-- 第二级选项卡 --> | ||||||
|  |     <div v-if="showLivel >= 2 && tabsLivel2Data.length > 0" class="custom-tabs-container"> | ||||||
|  |       <div | ||||||
|  |         v-for="item in tabsLivel2Data" | ||||||
|  |         :key="item.id" | ||||||
|  |         class="custom-tab-item" | ||||||
|  |         :class="{ | ||||||
|  |           active: active2Current === item.id, | ||||||
|  |           'all-tab': item.isAll, | ||||||
|  |         }" | ||||||
|  |         @click="handleCustomTabClick(2, item)" | ||||||
|  |       > | ||||||
|  |         {{ item.name }} | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |     <!-- 第三级选项卡 --> | ||||||
|  |     <div v-if="showLivel >= 3 && tabsLivel3Data.length > 0" class="custom-tabs-container"> | ||||||
|  |       <div | ||||||
|  |         v-for="item in tabsLivel3Data" | ||||||
|  |         :key="item.id" | ||||||
|  |         class="custom-tab-item" | ||||||
|  |         :class="{ | ||||||
|  |           active: active3Current === item.id, | ||||||
|  |           'all-tab': item.isAll, | ||||||
|  |         }" | ||||||
|  |         @click="handleCustomTabClick(3, item)" | ||||||
|  |       > | ||||||
|  |         {{ item.name }} | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script setup> | ||||||
|  | import { ref, watch, computed, onMounted, nextTick } from 'vue'; | ||||||
|  | 
 | ||||||
|  | const props = defineProps({ | ||||||
|  |   list: { | ||||||
|  |     type: Array, | ||||||
|  |     required: true, | ||||||
|  |     default: () => [ | ||||||
|  |       // { | ||||||
|  |       //   id: '71', | ||||||
|  |       //   level: 2, | ||||||
|  |       //   name: '蔬菜', | ||||||
|  |       //   parentId: '60', | ||||||
|  |       //   children: [ | ||||||
|  |       //     { | ||||||
|  |       //       id: '7101', | ||||||
|  |       //       level: 3, | ||||||
|  |       //       name: '茄果类', | ||||||
|  |       //       parentId: '71', | ||||||
|  |       //     }, | ||||||
|  |       //     { | ||||||
|  |       //       id: '7102', | ||||||
|  |       //       level: 3, | ||||||
|  |       //       name: '瓜类', | ||||||
|  |       //       parentId: '71', | ||||||
|  |       //     }, | ||||||
|  |       //     { | ||||||
|  |       //       id: '7103', | ||||||
|  |       //       level: 3, | ||||||
|  |       //       name: '叶菜类', | ||||||
|  |       //       parentId: '71', | ||||||
|  |       //     }, | ||||||
|  |       //   ], | ||||||
|  |       // }, | ||||||
|  |       // { | ||||||
|  |       //   id: '72', | ||||||
|  |       //   level: 2, | ||||||
|  |       //   name: '中药材', | ||||||
|  |       //   parentId: '60', | ||||||
|  |       //   children: [ | ||||||
|  |       //     { | ||||||
|  |       //       id: '7201', | ||||||
|  |       //       level: 3, | ||||||
|  |       //       name: '补益药', | ||||||
|  |       //       parentId: '72', | ||||||
|  |       //     }, | ||||||
|  |       //     { | ||||||
|  |       //       id: '7202', | ||||||
|  |       //       level: 3, | ||||||
|  |       //       name: '原材料', | ||||||
|  |       //       parentId: '72', | ||||||
|  |       //     }, | ||||||
|  |       //   ], | ||||||
|  |       // }, | ||||||
|  |       // { | ||||||
|  |       //   id: '73', | ||||||
|  |       //   level: 2, | ||||||
|  |       //   name: '水果', | ||||||
|  |       //   parentId: '60', | ||||||
|  |       //   children: [ | ||||||
|  |       //     { | ||||||
|  |       //       id: '7301', | ||||||
|  |       //       level: 3, | ||||||
|  |       //       name: '补益药', | ||||||
|  |       //       parentId: '73', | ||||||
|  |       //     }, | ||||||
|  |       //     { | ||||||
|  |       //       id: '7302', | ||||||
|  |       //       level: 3, | ||||||
|  |       //       name: '原材料', | ||||||
|  |       //       parentId: '73', | ||||||
|  |       //     }, | ||||||
|  |       //   ], | ||||||
|  |       // }, | ||||||
|  |     ], | ||||||
|  |   }, | ||||||
|  |   showLivel: { | ||||||
|  |     type: Number, | ||||||
|  |     default: 3, | ||||||
|  |     validator: (value) => [1, 2, 3].includes(value), | ||||||
|  |   }, | ||||||
|  |   fontSize: { | ||||||
|  |     type: String, | ||||||
|  |     default: '18px', | ||||||
|  |   }, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const emit = defineEmits(['select', 'change']); | ||||||
|  | 
 | ||||||
|  | // 当前选中的选项卡ID | ||||||
|  | const active1Current = ref(''); | ||||||
|  | const active2Current = ref(''); | ||||||
|  | const active3Current = ref(''); | ||||||
|  | 
 | ||||||
|  | // 创建"全部"选项的辅助函数 | ||||||
|  | const createAllOption = (level, parentId = null) => { | ||||||
|  |   return { | ||||||
|  |     id: `all-level-${level}`, | ||||||
|  |     name: '全部', | ||||||
|  |     level: level, | ||||||
|  |     parentId: parentId, | ||||||
|  |     isAll: true, // 标记为全部选项 | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 各级选项卡数据(自动添加全部选项) | ||||||
|  | const tabsLivel1Data = computed(() => { | ||||||
|  |   const allOption = createAllOption(1); | ||||||
|  |   return [allOption, ...props.list]; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const tabsLivel2Data = computed(() => { | ||||||
|  |   if (!active1Current.value) return []; | ||||||
|  | 
 | ||||||
|  |   // 如果一级选择的是"全部",则显示所有二级选项 | ||||||
|  |   if (active1Current.value === 'all-level-1') { | ||||||
|  |     const allChildren = props.list.flatMap((item) => item.children || []); | ||||||
|  |     // 只有当有二级数据时才添加"全部"选项 | ||||||
|  |     return allChildren.length > 0 ? [createAllOption(2, active1Current.value), ...allChildren] : []; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // 如果一级选择的是具体项,显示该项的子级 | ||||||
|  |   const selectedItem = props.list.find((item) => item.id === active1Current.value); | ||||||
|  |   const children = selectedItem?.children || []; | ||||||
|  |   // 只有当有二级数据时才添加"全部"选项 | ||||||
|  |   return children.length > 0 ? [createAllOption(2, active1Current.value), ...children] : []; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const tabsLivel3Data = computed(() => { | ||||||
|  |   if (!active2Current.value) return []; | ||||||
|  | 
 | ||||||
|  |   let children = []; | ||||||
|  | 
 | ||||||
|  |   // 获取当前二级选项对应的三级数据 | ||||||
|  |   if (active2Current.value === 'all-level-2') { | ||||||
|  |     // 二级选择全部时的逻辑 | ||||||
|  |     if (active1Current.value === 'all-level-1') { | ||||||
|  |       children = props.list.flatMap((item) => (item.children ? item.children.flatMap((child) => child.children || []) : [])); | ||||||
|  |     } else { | ||||||
|  |       const level1Item = props.list.find((item) => item.id === active1Current.value); | ||||||
|  |       children = level1Item?.children ? level1Item.children.flatMap((child) => child.children || []) : []; | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     // 二级选择具体项时的逻辑 | ||||||
|  |     let parentItem = null; | ||||||
|  |     if (active1Current.value === 'all-level-1') { | ||||||
|  |       for (const level1Item of props.list) { | ||||||
|  |         if (level1Item.children) { | ||||||
|  |           const found = level1Item.children.find((item) => item.id === active2Current.value); | ||||||
|  |           if (found) { | ||||||
|  |             parentItem = found; | ||||||
|  |             break; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       const level1Item = props.list.find((item) => item.id === active1Current.value); | ||||||
|  |       parentItem = level1Item?.children?.find((item) => item.id === active2Current.value); | ||||||
|  |     } | ||||||
|  |     children = parentItem?.children || []; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // 只有当有三级数据时才添加"全部"选项 | ||||||
|  |   return children.length > 0 ? [createAllOption(3, active2Current.value), ...children] : []; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | // 初始化选中状态 | ||||||
|  | const initializeSelection = () => { | ||||||
|  |   if (tabsLivel1Data.value.length > 0) { | ||||||
|  |     // 默认选中第一项(全部) | ||||||
|  |     active1Current.value = tabsLivel1Data.value[0].id; | ||||||
|  | 
 | ||||||
|  |     if (props.showLivel >= 2 && tabsLivel2Data.value.length > 0) { | ||||||
|  |       // 二级默认选中全部 | ||||||
|  |       active2Current.value = tabsLivel2Data.value[0].id; | ||||||
|  | 
 | ||||||
|  |       if (props.showLivel >= 3 && tabsLivel3Data.value.length > 0) { | ||||||
|  |         // 三级默认选中全部 | ||||||
|  |         active3Current.value = tabsLivel3Data.value[0].id; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // 初始化后立即触发一次选择事件 | ||||||
|  |     emitSelection(); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 获取当前选中的完整信息 | ||||||
|  | const getSelectedItems = () => { | ||||||
|  |   const selectedItems = []; | ||||||
|  | 
 | ||||||
|  |   // 第一级 | ||||||
|  |   if (active1Current.value) { | ||||||
|  |     const level1Item = tabsLivel1Data.value.find((item) => item.id === active1Current.value); | ||||||
|  |     if (level1Item) { | ||||||
|  |       selectedItems.push({ | ||||||
|  |         id: level1Item.id, | ||||||
|  |         name: level1Item.name, | ||||||
|  |         isAll: level1Item.isAll || false, | ||||||
|  |         ...level1Item, | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // 第二级 | ||||||
|  |   if (active2Current.value && props.showLivel >= 2) { | ||||||
|  |     const level2Item = tabsLivel2Data.value.find((item) => item.id === active2Current.value); | ||||||
|  |     if (level2Item) { | ||||||
|  |       selectedItems.push({ | ||||||
|  |         id: level2Item.id, | ||||||
|  |         name: level2Item.name, | ||||||
|  |         isAll: level2Item.isAll || false, | ||||||
|  |         ...level2Item, | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // 第三级 | ||||||
|  |   if (active3Current.value && props.showLivel >= 3) { | ||||||
|  |     const level3Item = tabsLivel3Data.value.find((item) => item.id === active3Current.value); | ||||||
|  |     if (level3Item) { | ||||||
|  |       selectedItems.push({ | ||||||
|  |         id: level3Item.id, | ||||||
|  |         name: level3Item.name, | ||||||
|  |         isAll: level3Item.isAll || false, | ||||||
|  |         ...level3Item, | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return selectedItems; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 触发选择事件 | ||||||
|  | const emitSelection = () => { | ||||||
|  |   const selectedItems = getSelectedItems(); | ||||||
|  |   emit('select', selectedItems); | ||||||
|  |   emit('change', selectedItems); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 第一级选项卡点击事件 | ||||||
|  | const handle1Click = (tabName) => { | ||||||
|  |   active1Current.value = tabName; | ||||||
|  |   // 重置下级选择为全部 | ||||||
|  |   if (props.showLivel >= 2) { | ||||||
|  |     const allOption = tabsLivel2Data.value.find((item) => item.isAll); | ||||||
|  |     active2Current.value = allOption ? allOption.id : ''; | ||||||
|  |   } | ||||||
|  |   if (props.showLivel >= 3) { | ||||||
|  |     const allOption = tabsLivel3Data.value.find((item) => item.isAll); | ||||||
|  |     active3Current.value = allOption ? allOption.id : ''; | ||||||
|  |   } | ||||||
|  |   emitSelection(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 第二级选项卡点击事件 | ||||||
|  | const handle2Click = (tabName) => { | ||||||
|  |   active2Current.value = tabName; | ||||||
|  |   // 重置下级选择为全部 | ||||||
|  |   if (props.showLivel >= 3) { | ||||||
|  |     const allOption = tabsLivel3Data.value.find((item) => item.isAll); | ||||||
|  |     active3Current.value = allOption ? allOption.id : ''; | ||||||
|  |   } | ||||||
|  |   emitSelection(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 第三级选项卡点击事件 | ||||||
|  | const handle3Click = (tabName) => { | ||||||
|  |   active3Current.value = tabName; | ||||||
|  |   emitSelection(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 自定义选项卡点击处理 | ||||||
|  | const handleCustomTabClick = (level, item) => { | ||||||
|  |   switch (level) { | ||||||
|  |     case 1: | ||||||
|  |       active1Current.value = item.id; | ||||||
|  |       if (props.showLivel >= 2) { | ||||||
|  |         const allOption = tabsLivel2Data.value.find((item) => item.isAll); | ||||||
|  |         active2Current.value = allOption ? allOption.id : ''; | ||||||
|  |       } | ||||||
|  |       if (props.showLivel >= 3) { | ||||||
|  |         const allOption = tabsLivel3Data.value.find((item) => item.isAll); | ||||||
|  |         active3Current.value = allOption ? allOption.id : ''; | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |     case 2: | ||||||
|  |       active2Current.value = item.id; | ||||||
|  |       if (props.showLivel >= 3) { | ||||||
|  |         const allOption = tabsLivel3Data.value.find((item) => item.isAll); | ||||||
|  |         active3Current.value = allOption ? allOption.id : ''; | ||||||
|  |       } | ||||||
|  |       break; | ||||||
|  |     case 3: | ||||||
|  |       active3Current.value = item.id; | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   emitSelection(); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // 监听props.list变化,重新初始化 | ||||||
|  | watch( | ||||||
|  |   () => props.list, | ||||||
|  |   (newList) => { | ||||||
|  |     if (newList && newList.length > 0) { | ||||||
|  |       nextTick(() => { | ||||||
|  |         initializeSelection(); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   { immediate: true, deep: true } | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | // 组件挂载时初始化 | ||||||
|  | onMounted(() => { | ||||||
|  |   if (props.list && props.list.length > 0) { | ||||||
|  |     initializeSelection(); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | // tabs时的样式 | ||||||
|  | .coustom-tabs-container { | ||||||
|  |   width: 100%; | ||||||
|  | 
 | ||||||
|  |   .el-tabs { | ||||||
|  |     margin-bottom: 10px; | ||||||
|  | 
 | ||||||
|  |     :deep(.el-tabs__header) { | ||||||
|  |       margin: 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     :deep(.el-tabs__item) { | ||||||
|  |       padding: 0 16px; | ||||||
|  |       height: 32px; | ||||||
|  |       line-height: 32px; | ||||||
|  |       font-size: v-bind('props.fontSize') !important; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // 为全部选项添加特殊样式 | ||||||
|  |     :deep(.el-tabs__item:first-child) { | ||||||
|  |       color: #67c23a; // 绿色,与图片中的样式一致 | ||||||
|  |       font-weight: 500; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     :deep(.el-tabs__nav-wrap:after) { | ||||||
|  |       background-color: transparent; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 自定义选项卡样式 | ||||||
|  | .coustom-div-container { | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  | .custom-tabs-container { | ||||||
|  |   display: flex; | ||||||
|  |   flex-wrap: wrap; /* 关键属性:允许换行 */ | ||||||
|  |   gap: 12px; /* 选项卡之间的间距 */ | ||||||
|  |   background: #fff; | ||||||
|  |   border-radius: 8px; | ||||||
|  |   margin-bottom: 16px; | ||||||
|  | } | ||||||
|  | .custom-tab-item { | ||||||
|  |   padding: 0 8px; | ||||||
|  |   cursor: pointer; | ||||||
|  |   transition: all 0.3s ease; | ||||||
|  |   white-space: nowrap; | ||||||
|  | 
 | ||||||
|  |   /* 使用传入的字体大小 */ | ||||||
|  |   font-size: v-bind('props.fontSize'); | ||||||
|  | 
 | ||||||
|  |   &:hover { | ||||||
|  |     color: $color-main; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   &.active { | ||||||
|  |     color: $color-main; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   &.all-tab { | ||||||
|  |     color: #323232; | ||||||
|  | 
 | ||||||
|  |     &.active { | ||||||
|  |       color: $color-main; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     &:hover { | ||||||
|  |       color: $color-main; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 响应式调整 */ | ||||||
|  | @media (max-width: 768px) { | ||||||
|  |   .custom-tab-item { | ||||||
|  |     padding: 6px 12px; | ||||||
|  |     font-size: 14px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -51,6 +51,7 @@ const toLink = (index) => { | |||||||
| </script> | </script> | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
| .ecommerce-left-menu-warp { | .ecommerce-left-menu-warp { | ||||||
|  |   padding: 0 30px 0 10px; | ||||||
|   width: 100%; |   width: 100%; | ||||||
|   height: 100%; |   height: 100%; | ||||||
|   .left-menu { |   .left-menu { | ||||||
|  | |||||||
| @ -3,7 +3,37 @@ | |||||||
|     <common current-name="agricultural"> |     <common current-name="agricultural"> | ||||||
|       <template #main> |       <template #main> | ||||||
|         <!-- <banner :imglist="bannerList"></banner> --> |         <!-- <banner :imglist="bannerList"></banner> --> | ||||||
|         <filtertop :list="treeList" @select="selected" @search="search"></filtertop> |         <!-- 原来的顶部筛选组件,不好用 --> | ||||||
|  |         <!-- <filtertop :list="treeList" @select="selected" @search="search"></filtertop> --> | ||||||
|  | 
 | ||||||
|  |         <!-- 顶部筛选条件 --> | ||||||
|  |         <div class="filter-container"> | ||||||
|  |           <div style="width: 40%; margin-left: 10px; margin-bottom: 10px"> | ||||||
|  |             <div class="search-container"> | ||||||
|  |               <div class="search-box"> | ||||||
|  |                 <input v-model="searchName" type="text" placeholder="请输入农资商品名称" class="search-input" /> | ||||||
|  |                 <button class="search-button" @click.stop="onQuery()"> | ||||||
|  |                   <svg | ||||||
|  |                     xmlns="http://www.w3.org/2000/svg" | ||||||
|  |                     width="16" | ||||||
|  |                     height="16" | ||||||
|  |                     viewBox="0 0 24 24" | ||||||
|  |                     fill="none" | ||||||
|  |                     stroke="currentColor" | ||||||
|  |                     stroke-width="2" | ||||||
|  |                     stroke-linecap="round" | ||||||
|  |                     stroke-linejoin="round" | ||||||
|  |                   > | ||||||
|  |                     <circle cx="11" cy="11" r="8"></circle> | ||||||
|  |                     <line x1="21" y1="21" x2="16.65" y2="16.65"></line> | ||||||
|  |                   </svg> | ||||||
|  |                 </button> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <costomTabs :list="treeList" @change="changeTabs"></costomTabs> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|         <div class="goods-list-warp"> |         <div class="goods-list-warp"> | ||||||
|           <div class="goods-list"> |           <div class="goods-list"> | ||||||
|             <template v-for="(n, index) in list" :key="n.id"> |             <template v-for="(n, index) in list" :key="n.id"> | ||||||
| @ -32,6 +62,7 @@ import common from './components/common.vue'; | |||||||
| import banner from './components/banner.vue'; | import banner from './components/banner.vue'; | ||||||
| import filtertop from './components/filtertop.vue'; | import filtertop from './components/filtertop.vue'; | ||||||
| import goodsItem from './components/goodsItem.vue'; | import goodsItem from './components/goodsItem.vue'; | ||||||
|  | import costomTabs from '@/components/costomTabs.vue'; | ||||||
| import { ref, reactive, onMounted, onBeforeMount, onUnmounted, watch, computed } from 'vue'; | import { ref, reactive, onMounted, onBeforeMount, onUnmounted, watch, computed } from 'vue'; | ||||||
| import { transaction, agriculturalList } from '@/apis/agricultural'; | import { transaction, agriculturalList } from '@/apis/agricultural'; | ||||||
| let treeList = reactive([ | let treeList = reactive([ | ||||||
| @ -71,7 +102,24 @@ onBeforeMount(() => { | |||||||
|   getTree(); |   getTree(); | ||||||
|   getList(); |   getList(); | ||||||
| }); | }); | ||||||
|  | const changeTabs = (paramsArr) => { | ||||||
|  |   console.log('tabs选项', paramsArr); | ||||||
|  |   let level1Id = 0; | ||||||
|  |   let level2Id = 0; | ||||||
|  |   let level3Id = 0; | ||||||
| 
 | 
 | ||||||
|  |   if (paramsArr.length >= 1) { | ||||||
|  |     level1Id = paramsArr[0]?.name == '全部' ? 0 : paramsArr[0]?.id || 0; | ||||||
|  |   } | ||||||
|  |   if (paramsArr.length >= 2) { | ||||||
|  |     level2Id = paramsArr[1]?.name == '全部' ? 0 : paramsArr[1]?.id || 0; | ||||||
|  |   } | ||||||
|  |   if (paramsArr.length >= 3) { | ||||||
|  |     level3Id = paramsArr[2]?.name == '全部' ? 0 : paramsArr[2]?.id || 0; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   console.log('处理后的ID:', level1Id, level2Id, level3Id); | ||||||
|  | }; | ||||||
| //获取农资商品分类 | //获取农资商品分类 | ||||||
| const getTree = () => { | const getTree = () => { | ||||||
|   transaction().then((res) => { |   transaction().then((res) => { | ||||||
| @ -84,6 +132,7 @@ const getTree = () => { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| //获取农资商品列表 | //获取农资商品列表 | ||||||
|  | let searchName = ref(''); | ||||||
| let list = reactive([]); | let list = reactive([]); | ||||||
| let params = reactive({ | let params = reactive({ | ||||||
|   current: 1, |   current: 1, | ||||||
| @ -119,9 +168,11 @@ const getList = (data) => { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // let bannerList = reactive(['images/ecommerce/' + 'banner.png', 'images/ecommerce/' + 'banner1.png']); | // let bannerList = reactive(['images/ecommerce/' + 'banner.png', 'images/ecommerce/' + 'banner1.png']); | ||||||
| 
 | const onQuery = () => { | ||||||
|  |   getList({ searchName: searchName.value }); | ||||||
|  | }; | ||||||
| const search = (data) => { | const search = (data) => { | ||||||
|   getList(data); |   getList(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const selected = (data) => { | const selected = (data) => { | ||||||
| @ -161,11 +212,60 @@ const selected = (data) => { | |||||||
|       background: $color-fff; |       background: $color-fff; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
|   /* 添加伪元素占位 */ |   /* 添加伪元素占位 */ | ||||||
|   .goods-list::after { |   .goods-list::after { | ||||||
|     content: ''; |     content: ''; | ||||||
|     flex: auto; |     flex: auto; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // 顶部筛选条件背景容器 | ||||||
|  | .filter-container { | ||||||
|  |   padding: 16px 16px 6px 16px; | ||||||
|  |   width: 100%; | ||||||
|  |   border-radius: 16px; | ||||||
|  |   text-align: left; | ||||||
|  |   background: $color-fff; | ||||||
|  |   // 搜索框样式 | ||||||
|  |   .search-container { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     padding: 0 16px 0 0; | ||||||
|  |     .search-box { | ||||||
|  |       position: relative; | ||||||
|  |       width: 100%; | ||||||
|  |       max-width: 600px; | ||||||
|  |     } | ||||||
|  |     .search-input { | ||||||
|  |       width: 100%; | ||||||
|  |       padding: 10px; | ||||||
|  |       border: 1px solid black; | ||||||
|  |       border-radius: 14px; | ||||||
|  |       font-size: 14px; | ||||||
|  |       color: #333; | ||||||
|  |       outline: none; | ||||||
|  |       transition: border-color 0.3s; | ||||||
|  |     } | ||||||
|  |     .search-input:focus { | ||||||
|  |       border-color: #409eff; | ||||||
|  |     } | ||||||
|  |     .search-input::placeholder { | ||||||
|  |       color: #999; | ||||||
|  |     } | ||||||
|  |     .search-button { | ||||||
|  |       position: absolute; | ||||||
|  |       right: -10px; | ||||||
|  |       top: 55%; | ||||||
|  |       transform: translateY(-50%); | ||||||
|  |       background: transparent; | ||||||
|  |       border: none; | ||||||
|  |       cursor: pointer; | ||||||
|  |       padding: 4px; | ||||||
|  |       color: #000; | ||||||
|  |     } | ||||||
|  |     .search-button:hover { | ||||||
|  |       color: #409eff; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| </style> | </style> | ||||||
|  | |||||||
| @ -3,7 +3,37 @@ | |||||||
|     <common current-name="supplier"> |     <common current-name="supplier"> | ||||||
|       <template #main> |       <template #main> | ||||||
|         <!-- <banner name="supplier" :imglist="bannerList"></banner> --> |         <!-- <banner name="supplier" :imglist="bannerList"></banner> --> | ||||||
|         <filtertop :list="treeList" @select="selected" @search="search"></filtertop> |         <!-- 原来的顶部筛选组件,不好用 --> | ||||||
|  |         <!-- <filtertop :list="treeList" @select="selected" @search="search"></filtertop> --> | ||||||
|  | 
 | ||||||
|  |         <!-- 顶部筛选条件 --> | ||||||
|  |         <div class="filter-container"> | ||||||
|  |           <div style="width: 40%; margin-left: 10px; margin-bottom: 10px"> | ||||||
|  |             <div class="search-container"> | ||||||
|  |               <div class="search-box"> | ||||||
|  |                 <input v-model="searchName" type="text" placeholder="请输入农资商品名称" class="search-input" /> | ||||||
|  |                 <button class="search-button" @click.stop="onQuery()"> | ||||||
|  |                   <svg | ||||||
|  |                     xmlns="http://www.w3.org/2000/svg" | ||||||
|  |                     width="16" | ||||||
|  |                     height="16" | ||||||
|  |                     viewBox="0 0 24 24" | ||||||
|  |                     fill="none" | ||||||
|  |                     stroke="currentColor" | ||||||
|  |                     stroke-width="2" | ||||||
|  |                     stroke-linecap="round" | ||||||
|  |                     stroke-linejoin="round" | ||||||
|  |                   > | ||||||
|  |                     <circle cx="11" cy="11" r="8"></circle> | ||||||
|  |                     <line x1="21" y1="21" x2="16.65" y2="16.65"></line> | ||||||
|  |                   </svg> | ||||||
|  |                 </button> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <costomTabs :list="treeList" @change="changeTabs"></costomTabs> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|         <div class="goods-list-warp"> |         <div class="goods-list-warp"> | ||||||
|           <div class="goods-list"> |           <div class="goods-list"> | ||||||
|             <template v-for="(n, index) in list" :key="n.id"> |             <template v-for="(n, index) in list" :key="n.id"> | ||||||
| @ -53,6 +83,7 @@ let list = reactive([ | |||||||
|   //   goodPrice: '25', |   //   goodPrice: '25', | ||||||
|   // }, |   // }, | ||||||
| ]); | ]); | ||||||
|  | let searchName = ref(''); | ||||||
| let params = reactive({ | let params = reactive({ | ||||||
|   current: 1, |   current: 1, | ||||||
|   size: 10, |   size: 10, | ||||||
| @ -65,6 +96,24 @@ let pagination = reactive({ | |||||||
|   total: 4, |   total: 4, | ||||||
| }); | }); | ||||||
| let bannerList = reactive(['images/ecommerce/' + 'banner1.png', 'images/ecommerce/' + 'banner1.png']); | let bannerList = reactive(['images/ecommerce/' + 'banner1.png', 'images/ecommerce/' + 'banner1.png']); | ||||||
|  | const changeTabs = (paramsArr) => { | ||||||
|  |   console.log('tabs选项', paramsArr); | ||||||
|  |   let level1Id = 0; | ||||||
|  |   let level2Id = 0; | ||||||
|  |   let level3Id = 0; | ||||||
|  | 
 | ||||||
|  |   if (paramsArr.length >= 1) { | ||||||
|  |     level1Id = paramsArr[0]?.name == '全部' ? 0 : paramsArr[0]?.id || 0; | ||||||
|  |   } | ||||||
|  |   if (paramsArr.length >= 2) { | ||||||
|  |     level2Id = paramsArr[1]?.name == '全部' ? 0 : paramsArr[1]?.id || 0; | ||||||
|  |   } | ||||||
|  |   if (paramsArr.length >= 3) { | ||||||
|  |     level3Id = paramsArr[2]?.name == '全部' ? 0 : paramsArr[2]?.id || 0; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   console.log('处理后的ID:', level1Id, level2Id, level3Id); | ||||||
|  | }; | ||||||
| const getList = (data) => { | const getList = (data) => { | ||||||
|   if (data) { |   if (data) { | ||||||
|     params.goodName = data.searchName; |     params.goodName = data.searchName; | ||||||
| @ -84,6 +133,9 @@ onMounted(() => { | |||||||
|   getTree(); |   getTree(); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | const onQuery = () => { | ||||||
|  |   getList({ searchName: searchName.value }); | ||||||
|  | }; | ||||||
| const search = (data) => { | const search = (data) => { | ||||||
|   getList(data); |   getList(data); | ||||||
| }; | }; | ||||||
| @ -151,4 +203,54 @@ const selected = (data) => { | |||||||
|     flex: auto; |     flex: auto; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // 顶部筛选条件背景容器 | ||||||
|  | .filter-container { | ||||||
|  |   padding: 16px 16px 6px 16px; | ||||||
|  |   width: 100%; | ||||||
|  |   border-radius: 16px; | ||||||
|  |   text-align: left; | ||||||
|  |   background: $color-fff; | ||||||
|  |   // 搜索框样式 | ||||||
|  |   .search-container { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     padding: 0 16px 0 0; | ||||||
|  |     .search-box { | ||||||
|  |       position: relative; | ||||||
|  |       width: 100%; | ||||||
|  |       max-width: 600px; | ||||||
|  |     } | ||||||
|  |     .search-input { | ||||||
|  |       width: 100%; | ||||||
|  |       padding: 10px; | ||||||
|  |       border: 1px solid black; | ||||||
|  |       border-radius: 14px; | ||||||
|  |       font-size: 14px; | ||||||
|  |       color: #333; | ||||||
|  |       outline: none; | ||||||
|  |       transition: border-color 0.3s; | ||||||
|  |     } | ||||||
|  |     .search-input:focus { | ||||||
|  |       border-color: #409eff; | ||||||
|  |     } | ||||||
|  |     .search-input::placeholder { | ||||||
|  |       color: #999; | ||||||
|  |     } | ||||||
|  |     .search-button { | ||||||
|  |       position: absolute; | ||||||
|  |       right: -10px; | ||||||
|  |       top: 55%; | ||||||
|  |       transform: translateY(-50%); | ||||||
|  |       background: transparent; | ||||||
|  |       border: none; | ||||||
|  |       cursor: pointer; | ||||||
|  |       padding: 4px; | ||||||
|  |       color: #000; | ||||||
|  |     } | ||||||
|  |     .search-button:hover { | ||||||
|  |       color: #409eff; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| </style> | </style> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user