Compare commits
	
		
			28 Commits
		
	
	
		
			44bb45327e
			...
			ebe909c4d7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | ebe909c4d7 | ||
|  | 825ec8affe | ||
|  | 9c66632135 | ||
|  | 6a060147a2 | ||
|  | fae3728f5a | ||
|  | b87e8d3346 | ||
|  | e0f195bdb1 | ||
|  | 1e9dd9bb3e | ||
|  | 70602bd077 | ||
|  | 98be4bc5ac | ||
|  | ead04355d0 | ||
|  | cc8091d04e | ||
|  | 2a277d1388 | ||
|  | 890d4436d9 | ||
|  | 3d98a1b9d7 | ||
|  | d18dcfd8f9 | ||
|  | 4caa3fb0da | ||
|  | f673fbed7f | ||
|  | ae87146c5f | ||
|  | c3852e1fb8 | ||
|  | 4e771fde21 | ||
|  | e0853e1416 | ||
|  | 4d358d130b | ||
|  | da4a2c509c | ||
|  | 904ed68377 | ||
|  | ae040fb280 | ||
|  | a6660e6d77 | ||
|  | 9c725735af | 
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -17,3 +17,6 @@ logs | |||||||
| .DS_Store | .DS_Store | ||||||
| .fleet | .fleet | ||||||
| .idea | .idea | ||||||
|  | .history/ | ||||||
|  | .history/** | ||||||
|  | **/.history/** | ||||||
							
								
								
									
										83
									
								
								.history/app/components/itemDetail/index_20250226145158.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								.history/app/components/itemDetail/index_20250226145158.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,83 @@ | |||||||
|  | <script setup> | ||||||
|  | import { showImagePreview } from 'vant'; | ||||||
|  | 
 | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | const props = defineProps({ | ||||||
|  |   detailInfo: { | ||||||
|  |     type: Object, | ||||||
|  |     default: null | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const filteredPriceRules = computed(() => { | ||||||
|  |   if (!props.detailInfo?.priceRules) return [] | ||||||
|  | 
 | ||||||
|  |   // 找到第一个price为空的索引 | ||||||
|  |   const emptyIndex = props.detailInfo.priceRules.findIndex(item => !item.price) | ||||||
|  | 
 | ||||||
|  |   if (emptyIndex === -1) { | ||||||
|  |     // 如果没有空价格,返回全部 | ||||||
|  |     return props.detailInfo.priceRules | ||||||
|  |   } else { | ||||||
|  |     // 如果有空价格,只返回到空价格之前的数据 | ||||||
|  |     return props.detailInfo.priceRules.slice(0, emptyIndex) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  | <div> | ||||||
|  |   <div class="flex justify-center"> | ||||||
|  |     <xImage class="h-188px" :src="detailInfo?.artwork?.hdPic"></xImage> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-[#fff] pt-[11px] mb-6px"> | ||||||
|  |     <div class="text-[#000] text-[16px] mb-[12px]">{{detailInfo?.artworkTitle}}</div> | ||||||
|  |     <div class="text-#575757 text-[14px] pb-8px"> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px]">{{$t('detail.text1')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.artistName??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text2')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.ruler??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text3')}}*{{$t('detail.text4')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.length}}*{{detailInfo?.artwork?.width}}cm</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text5')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.abstract??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px"> | ||||||
|  |     <div class="text-[#575757] text-[14px]">{{$t('detail.text6')}}:</div> | ||||||
|  |     <div class="text-#575757 text-14px font-bold">{{detailInfo?.startPriceCurrency}} {{detailInfo?.startPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px" v-if="detailInfo?.soldPrice"> | ||||||
|  |     <div class="text-[#B58047] text-[14px]">成交价:</div> | ||||||
|  |     <div class="text-#B58047 text-14px font-bold">{{detailInfo?.soldPriceCurrency}} {{detailInfo?.soldPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-#fff pt-12px pb-18px"> | ||||||
|  |     <div class="text-[#575757] text-[14px] mb-4px">{{$t('detail.text7')}}:</div> | ||||||
|  |     <div v-if="detailInfo?.priceRuleType!=='diy'"> | ||||||
|  |       <xImage :src="detailInfo?.priceRuleImage" alt=""/> | ||||||
|  |     </div> | ||||||
|  |     <div v-else class="mt-20px"> | ||||||
|  |       <div class="flex text-#575757 text-12px"> | ||||||
|  |         <div class="grow-1 text-center">序号</div> | ||||||
|  |         <div class="grow-1 text-center">叫价金额</div> | ||||||
|  |       </div> | ||||||
|  |       <div v-for="(item,index) of filteredPriceRules" :key="item.index" class="flex text-#575757 text-12px mt-10px"> | ||||||
|  |         <div class="grow-1 text-center">{{item.index}}</div> | ||||||
|  |         <div class="grow-1 text-center">{{item.price}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
							
								
								
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154608.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154608.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | <script setup> | ||||||
|  | import { showImagePreview } from 'vant'; | ||||||
|  | 
 | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | const props = defineProps({ | ||||||
|  |   detailInfo: { | ||||||
|  |     type: Object, | ||||||
|  |     default: null | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const filteredPriceRules = computed(() => { | ||||||
|  |   if (!props.detailInfo?.priceRules) return [] | ||||||
|  | 
 | ||||||
|  |   // 找到第一个price为空的索引 | ||||||
|  |   const emptyIndex = props.detailInfo.priceRules.findIndex(item => !item.price) | ||||||
|  | 
 | ||||||
|  |   if (emptyIndex === -1) { | ||||||
|  |     // 如果没有空价格,返回全部 | ||||||
|  |     return props.detailInfo.priceRules | ||||||
|  |   } else { | ||||||
|  |     // 如果有空价格,只返回到空价格之前的数据 | ||||||
|  |     return props.detailInfo.priceRules.slice(0, emptyIndex) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  | <div> | ||||||
|  |   <div class="flex justify-center"> | ||||||
|  |     <xImage class="h-188px" :src="detailInfo?.artwork?.hdPic"></xImage> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-[#fff] pt-[11px] mb-6px"> | ||||||
|  |     <div class="text-[#000] text-[16px] mb-[12px]">{{detailInfo?.artworkTitle}}</div> | ||||||
|  |     <div class="text-#575757 text-[14px] pb-8px"> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px]">{{$t('detail.text1')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.artistName??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text2')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.ruler??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text3')}}*{{$t('detail.text4')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.length}}*{{detailInfo?.artwork?.width}}cm</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text5')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.abstract??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px"> | ||||||
|  |     <div class="text-[#575757] text-[14px]">{{$t('detail.text6')}}:</div> | ||||||
|  |     <div class="text-#575757 text-14px font-bold">{{detailInfo?.startPriceCurrency}} {{detailInfo?.startPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px" v-if="detailInfo?.soldPrice"> | ||||||
|  |     <div class="text-[#B58047] text-[14px]">成交价:</div> | ||||||
|  |     <div class="text-#B58047 text-14px font-bold">{{detailInfo?.soldPriceCurrency}} {{detailInfo?.soldPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-#fff pt-12px pb-18px"> | ||||||
|  |     <div class="text-[#575757] text-[14px] mb-4px">{{$t('detail.text7')}}:</div> | ||||||
|  |     <div v-if="detailInfo?.priceRuleType!=='diy'"> | ||||||
|  |       <xImage :src="detailInfo?.priceRuleImage" alt=""/> | ||||||
|  |     </div> | ||||||
|  |     <div v-else class="mt-20px"> | ||||||
|  |       <div class="flex text-#575757 text-12px"> | ||||||
|  |         <div class="grow-1 text-center">序号</div> | ||||||
|  |         <div class="grow-1 text-center">叫价金额</div> | ||||||
|  |       </div> | ||||||
|  |       <div v-for="(item,index) of filteredPriceRules" :key="item.index" class="flex text-#575757 text-12px mt-10px"> | ||||||
|  |         <div class="grow-1 text-center">{{item.index}}</div> | ||||||
|  |         <div class="grow-1 text-center">{{item.price}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  |   <div class="flex"> | ||||||
|  |     <div>固定跳价</div> | ||||||
|  |     <div>{{ detailInfo?.priceRuleAdd }}</div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
							
								
								
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154630.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154630.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | <script setup> | ||||||
|  | import { showImagePreview } from 'vant'; | ||||||
|  | 
 | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | const props = defineProps({ | ||||||
|  |   detailInfo: { | ||||||
|  |     type: Object, | ||||||
|  |     default: null | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const filteredPriceRules = computed(() => { | ||||||
|  |   if (!props.detailInfo?.priceRules) return [] | ||||||
|  | 
 | ||||||
|  |   // 找到第一个price为空的索引 | ||||||
|  |   const emptyIndex = props.detailInfo.priceRules.findIndex(item => !item.price) | ||||||
|  | 
 | ||||||
|  |   if (emptyIndex === -1) { | ||||||
|  |     // 如果没有空价格,返回全部 | ||||||
|  |     return props.detailInfo.priceRules | ||||||
|  |   } else { | ||||||
|  |     // 如果有空价格,只返回到空价格之前的数据 | ||||||
|  |     return props.detailInfo.priceRules.slice(0, emptyIndex) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  | <div> | ||||||
|  |   <div class="flex justify-center"> | ||||||
|  |     <xImage class="h-188px" :src="detailInfo?.artwork?.hdPic"></xImage> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-[#fff] pt-[11px] mb-6px"> | ||||||
|  |     <div class="text-[#000] text-[16px] mb-[12px]">{{detailInfo?.artworkTitle}}</div> | ||||||
|  |     <div class="text-#575757 text-[14px] pb-8px"> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px]">{{$t('detail.text1')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.artistName??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text2')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.ruler??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text3')}}*{{$t('detail.text4')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.length}}*{{detailInfo?.artwork?.width}}cm</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text5')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.abstract??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px"> | ||||||
|  |     <div class="text-[#575757] text-[14px]">{{$t('detail.text6')}}:</div> | ||||||
|  |     <div class="text-#575757 text-14px font-bold">{{detailInfo?.startPriceCurrency}} {{detailInfo?.startPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px" v-if="detailInfo?.soldPrice"> | ||||||
|  |     <div class="text-[#B58047] text-[14px]">成交价:</div> | ||||||
|  |     <div class="text-#B58047 text-14px font-bold">{{detailInfo?.soldPriceCurrency}} {{detailInfo?.soldPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-#fff pt-12px pb-18px"> | ||||||
|  |     <div class="text-[#575757] text-[14px] mb-4px">{{$t('detail.text7')}}:</div> | ||||||
|  |     <div v-if="detailInfo?.priceRuleType!=='diy'"> | ||||||
|  |       <xImage :src="detailInfo?.priceRuleImage" alt=""/> | ||||||
|  |     </div> | ||||||
|  |     <div v-else class="mt-20px"> | ||||||
|  |       <div class="flex text-#575757 text-12px"> | ||||||
|  |         <div class="grow-1 text-center">序号</div> | ||||||
|  |         <div class="grow-1 text-center">叫价金额</div> | ||||||
|  |       </div> | ||||||
|  |       <div v-for="(item,index) of filteredPriceRules" :key="item.index" class="flex text-#575757 text-12px mt-10px"> | ||||||
|  |         <div class="grow-1 text-center">{{item.index}}</div> | ||||||
|  |         <div class="grow-1 text-center">{{item.price}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  |   <div class="flex text-[#575757] text-[14px]"> | ||||||
|  |     <div>固定跳价</div> | ||||||
|  |     <div>{{ detailInfo?.priceRuleAdd }}</div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
							
								
								
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154639.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154639.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | <script setup> | ||||||
|  | import { showImagePreview } from 'vant'; | ||||||
|  | 
 | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | const props = defineProps({ | ||||||
|  |   detailInfo: { | ||||||
|  |     type: Object, | ||||||
|  |     default: null | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const filteredPriceRules = computed(() => { | ||||||
|  |   if (!props.detailInfo?.priceRules) return [] | ||||||
|  | 
 | ||||||
|  |   // 找到第一个price为空的索引 | ||||||
|  |   const emptyIndex = props.detailInfo.priceRules.findIndex(item => !item.price) | ||||||
|  | 
 | ||||||
|  |   if (emptyIndex === -1) { | ||||||
|  |     // 如果没有空价格,返回全部 | ||||||
|  |     return props.detailInfo.priceRules | ||||||
|  |   } else { | ||||||
|  |     // 如果有空价格,只返回到空价格之前的数据 | ||||||
|  |     return props.detailInfo.priceRules.slice(0, emptyIndex) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  | <div> | ||||||
|  |   <div class="flex justify-center"> | ||||||
|  |     <xImage class="h-188px" :src="detailInfo?.artwork?.hdPic"></xImage> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-[#fff] pt-[11px] mb-6px"> | ||||||
|  |     <div class="text-[#000] text-[16px] mb-[12px]">{{detailInfo?.artworkTitle}}</div> | ||||||
|  |     <div class="text-#575757 text-[14px] pb-8px"> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px]">{{$t('detail.text1')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.artistName??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text2')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.ruler??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text3')}}*{{$t('detail.text4')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.length}}*{{detailInfo?.artwork?.width}}cm</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text5')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.abstract??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px"> | ||||||
|  |     <div class="text-[#575757] text-[14px]">{{$t('detail.text6')}}:</div> | ||||||
|  |     <div class="text-#575757 text-14px font-bold">{{detailInfo?.startPriceCurrency}} {{detailInfo?.startPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px" v-if="detailInfo?.soldPrice"> | ||||||
|  |     <div class="text-[#B58047] text-[14px]">成交价:</div> | ||||||
|  |     <div class="text-#B58047 text-14px font-bold">{{detailInfo?.soldPriceCurrency}} {{detailInfo?.soldPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-#fff pt-12px pb-18px"> | ||||||
|  |     <div class="text-[#575757] text-[14px] mb-4px">{{$t('detail.text7')}}:</div> | ||||||
|  |     <div v-if="detailInfo?.priceRuleType!=='diy'"> | ||||||
|  |       <xImage :src="detailInfo?.priceRuleImage" alt=""/> | ||||||
|  |     </div> | ||||||
|  |     <div v-else class="mt-20px"> | ||||||
|  |       <div class="flex text-#575757 text-12px"> | ||||||
|  |         <div class="grow-1 text-center">序号</div> | ||||||
|  |         <div class="grow-1 text-center">叫价金额</div> | ||||||
|  |       </div> | ||||||
|  |       <div v-for="(item,index) of filteredPriceRules" :key="item.index" class="flex text-#575757 text-12px mt-10px"> | ||||||
|  |         <div class="grow-1 text-center">{{item.index}}</div> | ||||||
|  |         <div class="grow-1 text-center">{{item.price}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  |   <div class="flex text-[#575757] text-[14px]"> | ||||||
|  |     <div>固定跳价:</div> | ||||||
|  |     <div>{{ detailInfo?.priceRuleAdd }}</div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
							
								
								
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154645.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154645.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | <script setup> | ||||||
|  | import { showImagePreview } from 'vant'; | ||||||
|  | 
 | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | const props = defineProps({ | ||||||
|  |   detailInfo: { | ||||||
|  |     type: Object, | ||||||
|  |     default: null | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const filteredPriceRules = computed(() => { | ||||||
|  |   if (!props.detailInfo?.priceRules) return [] | ||||||
|  | 
 | ||||||
|  |   // 找到第一个price为空的索引 | ||||||
|  |   const emptyIndex = props.detailInfo.priceRules.findIndex(item => !item.price) | ||||||
|  | 
 | ||||||
|  |   if (emptyIndex === -1) { | ||||||
|  |     // 如果没有空价格,返回全部 | ||||||
|  |     return props.detailInfo.priceRules | ||||||
|  |   } else { | ||||||
|  |     // 如果有空价格,只返回到空价格之前的数据 | ||||||
|  |     return props.detailInfo.priceRules.slice(0, emptyIndex) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  | <div> | ||||||
|  |   <div class="flex justify-center"> | ||||||
|  |     <xImage class="h-188px" :src="detailInfo?.artwork?.hdPic"></xImage> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-[#fff] pt-[11px] mb-6px"> | ||||||
|  |     <div class="text-[#000] text-[16px] mb-[12px]">{{detailInfo?.artworkTitle}}</div> | ||||||
|  |     <div class="text-#575757 text-[14px] pb-8px"> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px]">{{$t('detail.text1')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.artistName??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text2')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.ruler??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text3')}}*{{$t('detail.text4')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.length}}*{{detailInfo?.artwork?.width}}cm</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text5')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.abstract??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px"> | ||||||
|  |     <div class="text-[#575757] text-[14px]">{{$t('detail.text6')}}:</div> | ||||||
|  |     <div class="text-#575757 text-14px font-bold">{{detailInfo?.startPriceCurrency}} {{detailInfo?.startPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px" v-if="detailInfo?.soldPrice"> | ||||||
|  |     <div class="text-[#B58047] text-[14px]">成交价:</div> | ||||||
|  |     <div class="text-#B58047 text-14px font-bold">{{detailInfo?.soldPriceCurrency}} {{detailInfo?.soldPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-#fff pt-12px pb-18px"> | ||||||
|  |     <div class="text-[#575757] text-[14px] mb-4px">{{$t('detail.text7')}}:</div> | ||||||
|  |     <div v-if="detailInfo?.priceRuleType!=='diy'"> | ||||||
|  |       <xImage :src="detailInfo?.priceRuleImage" alt=""/> | ||||||
|  |     </div> | ||||||
|  |     <div v-else class="mt-20px"> | ||||||
|  |       <div class="flex text-#575757 text-12px"> | ||||||
|  |         <div class="grow-1 text-center">序号</div> | ||||||
|  |         <div class="grow-1 text-center">叫价金额</div> | ||||||
|  |       </div> | ||||||
|  |       <div v-for="(item,index) of filteredPriceRules" :key="item.index" class="flex text-#575757 text-12px mt-10px"> | ||||||
|  |         <div class="grow-1 text-center">{{item.index}}</div> | ||||||
|  |         <div class="grow-1 text-center">{{item.price}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  |   <div class="flex text-[#575757] text-[14px] justify-center"> | ||||||
|  |     <div>固定跳价:</div> | ||||||
|  |     <div>{{ detailInfo?.priceRuleAdd }}</div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
							
								
								
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154648.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154648.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | <script setup> | ||||||
|  | import { showImagePreview } from 'vant'; | ||||||
|  | 
 | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | const props = defineProps({ | ||||||
|  |   detailInfo: { | ||||||
|  |     type: Object, | ||||||
|  |     default: null | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const filteredPriceRules = computed(() => { | ||||||
|  |   if (!props.detailInfo?.priceRules) return [] | ||||||
|  | 
 | ||||||
|  |   // 找到第一个price为空的索引 | ||||||
|  |   const emptyIndex = props.detailInfo.priceRules.findIndex(item => !item.price) | ||||||
|  | 
 | ||||||
|  |   if (emptyIndex === -1) { | ||||||
|  |     // 如果没有空价格,返回全部 | ||||||
|  |     return props.detailInfo.priceRules | ||||||
|  |   } else { | ||||||
|  |     // 如果有空价格,只返回到空价格之前的数据 | ||||||
|  |     return props.detailInfo.priceRules.slice(0, emptyIndex) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  | <div> | ||||||
|  |   <div class="flex justify-center"> | ||||||
|  |     <xImage class="h-188px" :src="detailInfo?.artwork?.hdPic"></xImage> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-[#fff] pt-[11px] mb-6px"> | ||||||
|  |     <div class="text-[#000] text-[16px] mb-[12px]">{{detailInfo?.artworkTitle}}</div> | ||||||
|  |     <div class="text-#575757 text-[14px] pb-8px"> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px]">{{$t('detail.text1')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.artistName??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text2')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.ruler??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text3')}}*{{$t('detail.text4')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.length}}*{{detailInfo?.artwork?.width}}cm</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text5')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.abstract??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px"> | ||||||
|  |     <div class="text-[#575757] text-[14px]">{{$t('detail.text6')}}:</div> | ||||||
|  |     <div class="text-#575757 text-14px font-bold">{{detailInfo?.startPriceCurrency}} {{detailInfo?.startPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px" v-if="detailInfo?.soldPrice"> | ||||||
|  |     <div class="text-[#B58047] text-[14px]">成交价:</div> | ||||||
|  |     <div class="text-#B58047 text-14px font-bold">{{detailInfo?.soldPriceCurrency}} {{detailInfo?.soldPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-#fff pt-12px pb-18px"> | ||||||
|  |     <div class="text-[#575757] text-[14px] mb-4px">{{$t('detail.text7')}}:</div> | ||||||
|  |     <div v-if="detailInfo?.priceRuleType!=='diy'"> | ||||||
|  |       <xImage :src="detailInfo?.priceRuleImage" alt=""/> | ||||||
|  |     </div> | ||||||
|  |     <div v-else class="mt-20px"> | ||||||
|  |       <div class="flex text-#575757 text-12px"> | ||||||
|  |         <div class="grow-1 text-center">序号</div> | ||||||
|  |         <div class="grow-1 text-center">叫价金额</div> | ||||||
|  |       </div> | ||||||
|  |       <div v-for="(item,index) of filteredPriceRules" :key="item.index" class="flex text-#575757 text-12px mt-10px"> | ||||||
|  |         <div class="grow-1 text-center">{{item.index}}</div> | ||||||
|  |         <div class="grow-1 text-center">{{item.price}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  |   <div class="flex text-[#575757] text-[14px] justify-center"> | ||||||
|  |     <div>固定跳价:</div> | ||||||
|  |     <div>{{ detailInfo?.priceRuleAdd }}</div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
							
								
								
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154708.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154708.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | <script setup> | ||||||
|  | import { showImagePreview } from 'vant'; | ||||||
|  | 
 | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | const props = defineProps({ | ||||||
|  |   detailInfo: { | ||||||
|  |     type: Object, | ||||||
|  |     default: null | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const filteredPriceRules = computed(() => { | ||||||
|  |   if (!props.detailInfo?.priceRules) return [] | ||||||
|  | 
 | ||||||
|  |   // 找到第一个price为空的索引 | ||||||
|  |   const emptyIndex = props.detailInfo.priceRules.findIndex(item => !item.price) | ||||||
|  | 
 | ||||||
|  |   if (emptyIndex === -1) { | ||||||
|  |     // 如果没有空价格,返回全部 | ||||||
|  |     return props.detailInfo.priceRules | ||||||
|  |   } else { | ||||||
|  |     // 如果有空价格,只返回到空价格之前的数据 | ||||||
|  |     return props.detailInfo.priceRules.slice(0, emptyIndex) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  | <div> | ||||||
|  |   <div class="flex justify-center"> | ||||||
|  |     <xImage class="h-188px" :src="detailInfo?.artwork?.hdPic"></xImage> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-[#fff] pt-[11px] mb-6px"> | ||||||
|  |     <div class="text-[#000] text-[16px] mb-[12px]">{{detailInfo?.artworkTitle}}</div> | ||||||
|  |     <div class="text-#575757 text-[14px] pb-8px"> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px]">{{$t('detail.text1')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.artistName??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text2')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.ruler??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text3')}}*{{$t('detail.text4')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.length}}*{{detailInfo?.artwork?.width}}cm</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text5')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.abstract??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px"> | ||||||
|  |     <div class="text-[#575757] text-[14px]">{{$t('detail.text6')}}:</div> | ||||||
|  |     <div class="text-#575757 text-14px font-bold">{{detailInfo?.startPriceCurrency}} {{detailInfo?.startPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px" v-if="detailInfo?.soldPrice"> | ||||||
|  |     <div class="text-[#B58047] text-[14px]">成交价:</div> | ||||||
|  |     <div class="text-#B58047 text-14px font-bold">{{detailInfo?.soldPriceCurrency}} {{detailInfo?.soldPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-#fff pt-12px pb-18px"> | ||||||
|  |     <div class="text-[#575757] text-[14px] mb-4px">{{$t('detail.text7')}}:</div> | ||||||
|  |     <div v-if="detailInfo?.priceRuleType!=='diy'"> | ||||||
|  |       <xImage :src="detailInfo?.priceRuleImage" alt=""/> | ||||||
|  |     </div> | ||||||
|  |     <div v-else class="mt-20px"> | ||||||
|  |       <div class="flex text-#575757 text-12px"> | ||||||
|  |         <div class="grow-1 text-center">序号</div> | ||||||
|  |         <div class="grow-1 text-center">叫价金额</div> | ||||||
|  |       </div> | ||||||
|  |       <div v-for="(item,index) of filteredPriceRules" :key="item.index" class="flex text-#575757 text-12px mt-10px"> | ||||||
|  |         <div class="grow-1 text-center">{{item.index}}</div> | ||||||
|  |         <div class="grow-1 text-center">{{item.price}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  |   <div class="flex text-[#575757] text-[14px] justify-center"> | ||||||
|  |     <div>{{$t('detail.text9')}}:</div> | ||||||
|  |     <div>{{ detailInfo?.priceRuleAdd }}</div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
							
								
								
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154817.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								.history/app/components/itemDetail/index_20250306154817.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | |||||||
|  | <script setup> | ||||||
|  | import { showImagePreview } from 'vant'; | ||||||
|  | 
 | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | const props = defineProps({ | ||||||
|  |   detailInfo: { | ||||||
|  |     type: Object, | ||||||
|  |     default: null | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const filteredPriceRules = computed(() => { | ||||||
|  |   if (!props.detailInfo?.priceRules) return [] | ||||||
|  | 
 | ||||||
|  |   // 找到第一个price为空的索引 | ||||||
|  |   const emptyIndex = props.detailInfo.priceRules.findIndex(item => !item.price) | ||||||
|  | 
 | ||||||
|  |   if (emptyIndex === -1) { | ||||||
|  |     // 如果没有空价格,返回全部 | ||||||
|  |     return props.detailInfo.priceRules | ||||||
|  |   } else { | ||||||
|  |     // 如果有空价格,只返回到空价格之前的数据 | ||||||
|  |     return props.detailInfo.priceRules.slice(0, emptyIndex) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  | <div> | ||||||
|  |   <div class="flex justify-center"> | ||||||
|  |     <xImage class="h-188px" :src="detailInfo?.artwork?.hdPic"></xImage> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-[#fff] pt-[11px] mb-6px"> | ||||||
|  |     <div class="text-[#000] text-[16px] mb-[12px]">{{detailInfo?.artworkTitle}}</div> | ||||||
|  |     <div class="text-#575757 text-[14px] pb-8px"> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px]">{{$t('detail.text1')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.artistName??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text2')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.ruler??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text3')}}*{{$t('detail.text4')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.length}}*{{detailInfo?.artwork?.width}}cm</div> | ||||||
|  |       </div> | ||||||
|  |       <div class="flex mb-[4px]"> | ||||||
|  |         <div class="w-[70px] flex-shrink-0">{{$t('detail.text5')}}:</div> | ||||||
|  |         <div>{{detailInfo?.artwork?.abstract??'-'}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px"> | ||||||
|  |     <div class="text-[#575757] text-[14px]">{{$t('detail.text6')}}:</div> | ||||||
|  |     <div class="text-#575757 text-14px font-bold">{{detailInfo?.startPriceCurrency}} {{detailInfo?.startPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="flex px-[16px] bg-#fff h-[36px] items-center mb-6px" v-if="detailInfo?.soldPrice"> | ||||||
|  |     <div class="text-[#B58047] text-[14px]">成交价:</div> | ||||||
|  |     <div class="text-#B58047 text-14px font-bold">{{detailInfo?.soldPriceCurrency}} {{detailInfo?.soldPrice}}</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="px-[16px] bg-#fff pt-12px pb-18px"> | ||||||
|  |     <div class="text-[#575757] text-[14px] mb-4px">{{$t('detail.text7')}}:</div> | ||||||
|  |     <div v-if="detailInfo?.priceRuleType!=='diy'"> | ||||||
|  |       <xImage :src="detailInfo?.priceRuleImage" alt=""/> | ||||||
|  |     </div> | ||||||
|  |     <div v-else class="mt-20px"> | ||||||
|  |       <div class="flex text-#575757 text-12px"> | ||||||
|  |         <div class="grow-1 text-center">序号</div> | ||||||
|  |         <div class="grow-1 text-center">叫价金额</div> | ||||||
|  |       </div> | ||||||
|  |       <div v-for="(item,index) of filteredPriceRules" :key="item.index" class="flex text-#575757 text-12px mt-10px"> | ||||||
|  |         <div class="grow-1 text-center">{{item.index}}</div> | ||||||
|  |         <div class="grow-1 text-center">{{item.price}}</div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  |   <div class="flex text-[#575757] text-[14px] justify-center"> | ||||||
|  |     <div>{{$t('detail.text9')}}:</div> | ||||||
|  |     <div>{{ detailInfo?.priceRuleAdd }}</div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
| @ -0,0 +1,128 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | /** | ||||||
|  |  * 将数字格式化为"250XX"格式,其中XX是两位数 | ||||||
|  |  * @param {number} num - 要格式化的数字 | ||||||
|  |  * @return {string} - 格式化后的字符串 | ||||||
|  |  */ | ||||||
|  |  function formatNumber(num) { | ||||||
|  |   // 确保输入是有效数字 | ||||||
|  |   if (typeof num !== 'number' && isNaN(Number(num))) { | ||||||
|  |     throw new Error('输入必须是有效数字'); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // 转换为数字类型(以防输入是字符串数字) | ||||||
|  |   const number = Number(num); | ||||||
|  |    | ||||||
|  |   // 数字部分格式化为两位数,不足补0 | ||||||
|  |   const formattedNum = number.toString().padStart(2, '0'); | ||||||
|  |    | ||||||
|  |   // 添加前缀"250"并返回结果 | ||||||
|  |   return `250${formattedNum}`; | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item, index }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[55px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{ formatNumber(item.index) }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,128 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | /** | ||||||
|  |  * 将数字格式化为"250XX"格式,其中XX是两位数 | ||||||
|  |  * @param {number} num - 要格式化的数字 | ||||||
|  |  * @return {string} - 格式化后的字符串 | ||||||
|  |  */ | ||||||
|  |  function formatNumber(num) { | ||||||
|  |   // 确保输入是有效数字 | ||||||
|  |   if (typeof num !== 'number' && isNaN(Number(num))) { | ||||||
|  |     throw new Error('输入必须是有效数字'); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // 转换为数字类型(以防输入是字符串数字) | ||||||
|  |   const number = Number(num); | ||||||
|  |    | ||||||
|  |   // 数字部分格式化为两位数,不足补0 | ||||||
|  |   const formattedNum = number.toString().padStart(2, '0'); | ||||||
|  |    | ||||||
|  |   // 添加前缀"250"并返回结果 | ||||||
|  |   return `250${formattedNum}`; | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList.slice(0,1)"  :column-count="2"> | ||||||
|  |             <template #default="{ item, index }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[55px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{ formatNumber(item.index) }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,128 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   // pageRef.value.page++ | ||||||
|  |   // const { finished } = await getArtworkList() | ||||||
|  |   // localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | /** | ||||||
|  |  * 将数字格式化为"250XX"格式,其中XX是两位数 | ||||||
|  |  * @param {number} num - 要格式化的数字 | ||||||
|  |  * @return {string} - 格式化后的字符串 | ||||||
|  |  */ | ||||||
|  |  function formatNumber(num) { | ||||||
|  |   // 确保输入是有效数字 | ||||||
|  |   if (typeof num !== 'number' && isNaN(Number(num))) { | ||||||
|  |     throw new Error('输入必须是有效数字'); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // 转换为数字类型(以防输入是字符串数字) | ||||||
|  |   const number = Number(num); | ||||||
|  |    | ||||||
|  |   // 数字部分格式化为两位数,不足补0 | ||||||
|  |   const formattedNum = number.toString().padStart(2, '0'); | ||||||
|  |    | ||||||
|  |   // 添加前缀"250"并返回结果 | ||||||
|  |   return `250${formattedNum}`; | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList.slice(0,1)"  :column-count="2"> | ||||||
|  |             <template #default="{ item, index }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[55px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{ formatNumber(item.index) }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,128 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   // pageRef.value.page++ | ||||||
|  |   // const { finished } = await getArtworkList() | ||||||
|  |   // localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | /** | ||||||
|  |  * 将数字格式化为"250XX"格式,其中XX是两位数 | ||||||
|  |  * @param {number} num - 要格式化的数字 | ||||||
|  |  * @return {string} - 格式化后的字符串 | ||||||
|  |  */ | ||||||
|  |  function formatNumber(num) { | ||||||
|  |   // 确保输入是有效数字 | ||||||
|  |   if (typeof num !== 'number' && isNaN(Number(num))) { | ||||||
|  |     throw new Error('输入必须是有效数字'); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // 转换为数字类型(以防输入是字符串数字) | ||||||
|  |   const number = Number(num); | ||||||
|  |    | ||||||
|  |   // 数字部分格式化为两位数,不足补0 | ||||||
|  |   const formattedNum = number.toString().padStart(2, '0'); | ||||||
|  |    | ||||||
|  |   // 添加前缀"250"并返回结果 | ||||||
|  |   return `250${formattedNum}`; | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList.slice(0,1)"  :column-count="2"> | ||||||
|  |             <template #default="{ item, index }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[55px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{ formatNumber(item.index) }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,128 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | /** | ||||||
|  |  * 将数字格式化为"250XX"格式,其中XX是两位数 | ||||||
|  |  * @param {number} num - 要格式化的数字 | ||||||
|  |  * @return {string} - 格式化后的字符串 | ||||||
|  |  */ | ||||||
|  |  function formatNumber(num) { | ||||||
|  |   // 确保输入是有效数字 | ||||||
|  |   if (typeof num !== 'number' && isNaN(Number(num))) { | ||||||
|  |     throw new Error('输入必须是有效数字'); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // 转换为数字类型(以防输入是字符串数字) | ||||||
|  |   const number = Number(num); | ||||||
|  |    | ||||||
|  |   // 数字部分格式化为两位数,不足补0 | ||||||
|  |   const formattedNum = number.toString().padStart(2, '0'); | ||||||
|  |    | ||||||
|  |   // 添加前缀"250"并返回结果 | ||||||
|  |   return `250${formattedNum}`; | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item, index }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[55px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{ formatNumber(item.index) }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,128 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | /** | ||||||
|  |  * 将数字格式化为"250XX"格式,其中XX是两位数 | ||||||
|  |  * @param {number} num - 要格式化的数字 | ||||||
|  |  * @return {string} - 格式化后的字符串 | ||||||
|  |  */ | ||||||
|  |  function formatNumber(num) { | ||||||
|  |   // 确保输入是有效数字 | ||||||
|  |   if (typeof num !== 'number' && isNaN(Number(num))) { | ||||||
|  |     throw new Error('输入必须是有效数字'); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // 转换为数字类型(以防输入是字符串数字) | ||||||
|  |   const number = Number(num); | ||||||
|  |    | ||||||
|  |   // 数字部分格式化为两位数,不足补0 | ||||||
|  |   const formattedNum = number.toString().padStart(2, '0'); | ||||||
|  |    | ||||||
|  |   // 添加前缀"250"并返回结果 | ||||||
|  |   return `250${formattedNum}`; | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item, index }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[55px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{ formatNumber(item.index) }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,128 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | /** | ||||||
|  |  * 将数字格式化为"250XX"格式,其中XX是两位数 | ||||||
|  |  * @param {number} num - 要格式化的数字 | ||||||
|  |  * @return {string} - 格式化后的字符串 | ||||||
|  |  */ | ||||||
|  |  function formatNumber(num) { | ||||||
|  |   // 确保输入是有效数字 | ||||||
|  |   if (typeof num !== 'number' && isNaN(Number(num))) { | ||||||
|  |     throw new Error('输入必须是有效数字'); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // 转换为数字类型(以防输入是字符串数字) | ||||||
|  |   const number = Number(num); | ||||||
|  |    | ||||||
|  |   // 数字部分格式化为两位数,不足补0 | ||||||
|  |   const formattedNum = number.toString().padStart(2, '0'); | ||||||
|  |    | ||||||
|  |   // 添加前缀"250"并返回结果 | ||||||
|  |   return `250${formattedNum}`; | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item, index }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[55px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,128 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | /** | ||||||
|  |  * 将数字格式化为"250XX"格式,其中XX是两位数 | ||||||
|  |  * @param {number} num - 要格式化的数字 | ||||||
|  |  * @return {string} - 格式化后的字符串 | ||||||
|  |  */ | ||||||
|  |  function formatNumber(num) { | ||||||
|  |   // 确保输入是有效数字 | ||||||
|  |   if (typeof num !== 'number' && isNaN(Number(num))) { | ||||||
|  |     throw new Error('输入必须是有效数字'); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // 转换为数字类型(以防输入是字符串数字) | ||||||
|  |   const number = Number(num); | ||||||
|  |    | ||||||
|  |   // 数字部分格式化为两位数,不足补0 | ||||||
|  |   const formattedNum = number.toString().padStart(2, '0'); | ||||||
|  |    | ||||||
|  |   // 添加前缀"250"并返回结果 | ||||||
|  |   return `250${formattedNum}`; | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item, index }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,108 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item, index }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,139 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item, index }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <!-- 骨架屏,在图片加载完成前显示 --> | ||||||
|  |                   <van-skeleton | ||||||
|  |                     title | ||||||
|  |                     :row="0" | ||||||
|  |                     class="w-full aspect-ratio-square rounded-4px overflow-hidden" | ||||||
|  |                     v-if="!imageLoadingStatus[item.id]" | ||||||
|  |                   /> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,139 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <!-- 骨架屏,在图片加载完成前显示 --> | ||||||
|  |                   <van-skeleton | ||||||
|  |                     title | ||||||
|  |                     :row="0" | ||||||
|  |                     class="w-full aspect-ratio-square rounded-4px overflow-hidden" | ||||||
|  |                     v-if="!imageLoadingStatus[item.id]" | ||||||
|  |                   /> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,139 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <!-- 骨架屏,在图片加载完成前显示 --> | ||||||
|  |                   <van-skeleton | ||||||
|  |                     title | ||||||
|  |                     :row="0" | ||||||
|  |                     class="w-full aspect-ratio-square rounded-4px overflow-hidden" | ||||||
|  |                     v-if="!imageLoadingStatus[item.id]" | ||||||
|  |                   /> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,139 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <!-- 骨架屏,在图片加载完成前显示 --> | ||||||
|  |                   <van-skeleton | ||||||
|  |                     title | ||||||
|  |                     :row="0" | ||||||
|  |                     class="w-full aspect-ratio-square rounded-4px overflow-hidden" | ||||||
|  |                     v-if="!imageLoadingStatus[item.id]" | ||||||
|  |                   /> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,146 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton   v-if="!imageLoadingStatus[item.id]"> | ||||||
|  |   <template #template> | ||||||
|  |     <div :style="{ display: 'flex', width: '100%' }"> | ||||||
|  |       <van-skeleton-image /> | ||||||
|  |       <div :style="{ flex: 1, marginLeft: '16px' }"> | ||||||
|  |         <van-skeleton-paragraph row-width="60%" /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,146 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton   v-if="!imageLoadingStatus[item.id]"> | ||||||
|  |   <template #template> | ||||||
|  |     <div :style="{ display: 'flex', width: '100%' }"> | ||||||
|  |       <van-skeleton-image /> | ||||||
|  |       <div :style="{ flex: 1, marginLeft: '16px' }"> | ||||||
|  |         <van-skeleton-paragraph row-width="60%" /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton   v-if="!imageLoadingStatus[item.id]"> | ||||||
|  |   <template #template> | ||||||
|  |     <div :style="{ display: 'flex', width: '100%' }"> | ||||||
|  |       <van-skeleton-image /> | ||||||
|  |      <van-skeleton-paragraph row-width="60%" /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton   v-if="!imageLoadingStatus[item.id]"> | ||||||
|  |   <template #template> | ||||||
|  |     <div :style="{ display: 'flex', width: '100%' }"> | ||||||
|  |       <van-skeleton-image /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton   v-if="!imageLoadingStatus[item.id]"> | ||||||
|  |   <template #template> | ||||||
|  |     <div> | ||||||
|  |       <van-skeleton-image /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton   v-if="!imageLoadingStatus[item.id]"> | ||||||
|  |   <template #template> | ||||||
|  |     <div> | ||||||
|  |       <van-skeleton-image class="w-full" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton   > | ||||||
|  |   <template #template> | ||||||
|  |     <div> | ||||||
|  |       <van-skeleton-image class="w-full" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton   > | ||||||
|  |   <template #template> | ||||||
|  |     <div> | ||||||
|  |       <van-skeleton-image class="w-full flex flex-col" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div> | ||||||
|  |       <van-skeleton-image class="w-full" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div> | ||||||
|  |       <van-skeleton-image class="w-full" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="w-full" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="w-full" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="w-full flex-1" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="w-full flex-1" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="w-full flex-1" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="!w-full flex-1" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,144 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="!w-full flex-1 h-100px" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="!w-full flex-1 h-100px" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="!w-full flex-1 h-200px" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="!w-full flex-1 !h-200px" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image class="!w-full flex-1 !h-400px" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image style="--van-skeleton-image-size: 100%" class="!w-full flex-1 !h-400px" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image style="--van-skeleton-image-size: 200px" class="!w-full flex-1 !h-400px" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image style="--van-skeleton-image-size: 200px" class="!w-full flex-1" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image style="--van-skeleton-image-size: 500px" class="!w-full flex-1" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image style="height;: 500px" class="!w-full flex-1" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image style="height: 500px" class="!w-full flex-1" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,142 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                | ||||||
|  |                   <van-skeleton class="flex flex-col !p-0"  > | ||||||
|  |   <template #template> | ||||||
|  |     <div class="flex flex-col"> | ||||||
|  |       <van-skeleton-image style="height: 500px" class="!w-full flex-1" /> | ||||||
|  |      <van-skeleton-paragraph /> | ||||||
|  |         <van-skeleton-paragraph /> | ||||||
|  |     </div> | ||||||
|  |   </template> | ||||||
|  | </van-skeleton> | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 添加方形比例的样式 */ | ||||||
|  | .aspect-ratio-square { | ||||||
|  |   aspect-ratio: 1 / 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,189 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <!-- 自定义骨架屏 --> | ||||||
|  |                   <div  | ||||||
|  |                     v-if="!imageLoadingStatus[item.id]"  | ||||||
|  |                     class="custom-skeleton rounded-4px overflow-hidden" | ||||||
|  |                   > | ||||||
|  |                     <div class="skeleton-image"></div> | ||||||
|  |                     <div class="skeleton-content"> | ||||||
|  |                       <div class="skeleton-title"></div> | ||||||
|  |                       <div class="skeleton-text"></div> | ||||||
|  |                       <div class="skeleton-text"></div> | ||||||
|  |                     </div> | ||||||
|  |                   </div> | ||||||
|  |                    | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                       :class="{'z-10': !imageLoadingStatus[item.id]}" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]" :class="{'hidden': !imageLoadingStatus[item.id]}"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 自定义骨架屏样式 */ | ||||||
|  | .custom-skeleton { | ||||||
|  |   width: 100%; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   background-color: #fff; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-image { | ||||||
|  |   width: 100%; | ||||||
|  |   padding-bottom: 100%; /* 保持1:1的宽高比 */ | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-content { | ||||||
|  |   padding: 8px 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-title { | ||||||
|  |   height: 16px; | ||||||
|  |   margin-bottom: 8px; | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  |   border-radius: 2px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-text { | ||||||
|  |   height: 12px; | ||||||
|  |   margin-top: 4px; | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  |   border-radius: 2px; | ||||||
|  |   width: 60%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes skeleton-loading { | ||||||
|  |   0% { | ||||||
|  |     background-position: 100% 50%; | ||||||
|  |   } | ||||||
|  |   100% { | ||||||
|  |     background-position: 0 50%; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,189 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="itemList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <!-- 自定义骨架屏 --> | ||||||
|  |                   <div  | ||||||
|  |                     v-if="!imageLoadingStatus[item.id]"  | ||||||
|  |                     class="custom-skeleton rounded-4px overflow-hidden" | ||||||
|  |                   > | ||||||
|  |                     <div class="skeleton-image"></div> | ||||||
|  |                     <div class="skeleton-content"> | ||||||
|  |                       <div class="skeleton-title"></div> | ||||||
|  |                       <div class="skeleton-text"></div> | ||||||
|  |                       <div class="skeleton-text"></div> | ||||||
|  |                     </div> | ||||||
|  |                   </div> | ||||||
|  |                    | ||||||
|  |                   <img | ||||||
|  |                       :src="item.artwork?.hdPic" | ||||||
|  |                       class="w-full object-cover rounded-4px" | ||||||
|  |                       :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                       @load="handleImageLoad(item.id)" | ||||||
|  |                       @error="handleImageError(item.id)" | ||||||
|  |                   /> | ||||||
|  |                   <div | ||||||
|  |                       class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                       :class="{'z-10': !imageLoadingStatus[item.id]}" | ||||||
|  |                   > | ||||||
|  |                     Lot{{item.index+25000 }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="pt-[8px]" :class="{'hidden': !imageLoadingStatus[item.id]}"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 自定义骨架屏样式 */ | ||||||
|  | .custom-skeleton { | ||||||
|  |   width: 100%; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   background-color: #fff; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-image { | ||||||
|  |   width: 100%; | ||||||
|  |   padding-bottom: 100%; /* 保持1:1的宽高比 */ | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-content { | ||||||
|  |   padding: 8px 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-title { | ||||||
|  |   height: 16px; | ||||||
|  |   margin-bottom: 8px; | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  |   border-radius: 2px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-text { | ||||||
|  |   height: 12px; | ||||||
|  |   margin-top: 4px; | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  |   border-radius: 2px; | ||||||
|  |   width: 60%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes skeleton-loading { | ||||||
|  |   0% { | ||||||
|  |     background-position: 100% 50%; | ||||||
|  |   } | ||||||
|  |   100% { | ||||||
|  |     background-position: 0 50%; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,209 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref, computed } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 生成骨架屏列表数据 | ||||||
|  | const skeletonList = computed(() => { | ||||||
|  |   // 如果有实际数据,返回空数组 | ||||||
|  |   if (itemList.value && itemList.value.length > 0) return [] | ||||||
|  |   // 否则返回6个骨架屏项目 | ||||||
|  |   return Array(6).fill().map((_, index) => ({ | ||||||
|  |     id: `skeleton-${index}`, | ||||||
|  |     isSkeletonItem: true | ||||||
|  |   })) | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 合并实际列表和骨架屏列表 | ||||||
|  | const displayList = computed(() => { | ||||||
|  |   if (itemList.value && itemList.value.length > 0) return itemList.value | ||||||
|  |   return skeletonList.value | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   if (item.isSkeletonItem) return | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="displayList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <!-- 自定义骨架屏 --> | ||||||
|  |                   <div  | ||||||
|  |                     v-if="item.isSkeletonItem || !imageLoadingStatus[item.id]"  | ||||||
|  |                     class="custom-skeleton rounded-4px overflow-hidden" | ||||||
|  |                   > | ||||||
|  |                     <div class="skeleton-image"></div> | ||||||
|  |                     <div class="skeleton-content"> | ||||||
|  |                       <div class="skeleton-title"></div> | ||||||
|  |                       <div class="skeleton-text"></div> | ||||||
|  |                       <div class="skeleton-text"></div> | ||||||
|  |                     </div> | ||||||
|  |                   </div> | ||||||
|  |                    | ||||||
|  |                   <template v-if="!item.isSkeletonItem"> | ||||||
|  |                     <img | ||||||
|  |                         :src="item.artwork?.hdPic" | ||||||
|  |                         class="w-full object-cover rounded-4px" | ||||||
|  |                         :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                         @load="handleImageLoad(item.id)" | ||||||
|  |                         @error="handleImageError(item.id)" | ||||||
|  |                     /> | ||||||
|  |                     <div | ||||||
|  |                         class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                         :class="{'z-10': !imageLoadingStatus[item.id]}" | ||||||
|  |                     > | ||||||
|  |                       Lot{{item.index+25000 }} | ||||||
|  |                     </div> | ||||||
|  |                   </template> | ||||||
|  |                 </div> | ||||||
|  |                 <div v-if="!item.isSkeletonItem" class="pt-[8px]" :class="{'hidden': !imageLoadingStatus[item.id]}"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 自定义骨架屏样式 */ | ||||||
|  | .custom-skeleton { | ||||||
|  |   width: 100%; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   background-color: #fff; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-image { | ||||||
|  |   width: 100%; | ||||||
|  |   padding-bottom: 100%; /* 保持1:1的宽高比 */ | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-content { | ||||||
|  |   padding: 8px 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-title { | ||||||
|  |   height: 16px; | ||||||
|  |   margin-bottom: 8px; | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  |   border-radius: 2px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-text { | ||||||
|  |   height: 12px; | ||||||
|  |   margin-top: 4px; | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  |   border-radius: 2px; | ||||||
|  |   width: 60%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes skeleton-loading { | ||||||
|  |   0% { | ||||||
|  |     background-position: 100% 50%; | ||||||
|  |   } | ||||||
|  |   100% { | ||||||
|  |     background-position: 0 50%; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,209 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref, computed } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 生成骨架屏列表数据 | ||||||
|  | const skeletonList = computed(() => { | ||||||
|  |   // 如果有实际数据,返回空数组 | ||||||
|  |   if (itemList.value && itemList.value.length > 0) return [] | ||||||
|  |   // 否则返回6个骨架屏项目 | ||||||
|  |   return Array(6).fill().map((_, index) => ({ | ||||||
|  |     id: `skeleton-${index}`, | ||||||
|  |     isSkeletonItem: true | ||||||
|  |   })) | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 合并实际列表和骨架屏列表 | ||||||
|  | const displayList = computed(() => { | ||||||
|  |   if (itemList.value && itemList.value.length > 0) return itemList.value | ||||||
|  |   return skeletonList.value | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   if (item.isSkeletonItem) return | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="displayList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <!-- 自定义骨架屏 --> | ||||||
|  |                   <div  | ||||||
|  |                     v-if="item.isSkeletonItem || !imageLoadingStatus[item.id]"  | ||||||
|  |                     class="custom-skeleton rounded-4px overflow-hidden" | ||||||
|  |                   > | ||||||
|  |                     <div class="skeleton-image"></div> | ||||||
|  |                     <div class="skeleton-content"> | ||||||
|  |                       <div class="skeleton-title"></div> | ||||||
|  |                       <div class="skeleton-text"></div> | ||||||
|  |                       <div class="skeleton-text"></div> | ||||||
|  |                     </div> | ||||||
|  |                   </div> | ||||||
|  |                    | ||||||
|  |                   <template v-if="!item.isSkeletonItem"> | ||||||
|  |                     <img | ||||||
|  |                         :src="item.artwork?.hdPic" | ||||||
|  |                         class="w-full object-cover rounded-4px" | ||||||
|  |                         :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                         @load="handleImageLoad(item.id)" | ||||||
|  |                         @error="handleImageError(item.id)" | ||||||
|  |                     /> | ||||||
|  |                     <div | ||||||
|  |                         class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                         :class="{'z-10': !imageLoadingStatus[item.id]}" | ||||||
|  |                     > | ||||||
|  |                       Lot{{item.index+25000 }} | ||||||
|  |                     </div> | ||||||
|  |                   </template> | ||||||
|  |                 </div> | ||||||
|  |                 <div v-if="!item.isSkeletonItem" class="pt-[8px]" :class="{'hidden': !imageLoadingStatus[item.id]}"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 自定义骨架屏样式 */ | ||||||
|  | .custom-skeleton { | ||||||
|  |   width: 100%; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   background-color: #fff; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-image { | ||||||
|  |   width: 100%; | ||||||
|  |   padding-bottom: 100%; /* 保持1:1的宽高比 */ | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-content { | ||||||
|  |   padding: 8px 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-title { | ||||||
|  |   height: 16px; | ||||||
|  |   margin-bottom: 8px; | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  |   border-radius: 2px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-text { | ||||||
|  |   height: 12px; | ||||||
|  |   margin-top: 4px; | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  |   border-radius: 2px; | ||||||
|  |   width: 60%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes skeleton-loading { | ||||||
|  |   0% { | ||||||
|  |     background-position: 100% 50%; | ||||||
|  |   } | ||||||
|  |   100% { | ||||||
|  |     background-position: 0 50%; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,209 @@ | |||||||
|  | <script setup> | ||||||
|  | import { ref, computed } from 'vue' | ||||||
|  | import { goodStore } from "@/stores/goods" | ||||||
|  | import DetailPopup from '../DetailPopup/index.vue' | ||||||
|  | import WaterfallFlow from '@/components/waterfallFlow/index.vue' | ||||||
|  | const { | ||||||
|  |   itemList, | ||||||
|  |   pageRef, | ||||||
|  |   currentItem, | ||||||
|  |   loading: storeLoading, | ||||||
|  |   getArtworkList, | ||||||
|  | } = goodStore() | ||||||
|  | 
 | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 记录每个图片的加载状态 | ||||||
|  | const imageLoadingStatus = ref({}) | ||||||
|  | 
 | ||||||
|  | // 生成骨架屏列表数据 | ||||||
|  | const skeletonList = computed(() => { | ||||||
|  |   // 如果有实际数据,返回空数组 | ||||||
|  |   if (itemList.value && itemList.value.length > 0) return [] | ||||||
|  |   // 否则返回6个骨架屏项目 | ||||||
|  |   return Array(6).fill().map((_, index) => ({ | ||||||
|  |     id: `skeleton-${index}`, | ||||||
|  |     isSkeletonItem: true | ||||||
|  |   })) | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 合并实际列表和骨架屏列表 | ||||||
|  | const displayList = computed(() => { | ||||||
|  |   if (itemList.value && itemList.value.length > 0) return itemList.value | ||||||
|  |   return skeletonList.value | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 图片加载完成处理函数 | ||||||
|  | const handleImageLoad = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 图片加载错误处理函数 | ||||||
|  | const handleImageError = (itemId) => { | ||||||
|  |   imageLoadingStatus.value[itemId] = true // 也标记为加载完成,避免一直显示骨架屏 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 加载更多 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 刷新 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     // 重置图片加载状态 | ||||||
|  |     imageLoadingStatus.value = {} | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 打开详情 | ||||||
|  | const openShow = async (item) => { | ||||||
|  |   if (item.isSkeletonItem) return | ||||||
|  |   localState.value.showDetail = true | ||||||
|  |   currentItem.value = item | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="px-[16px] pt-[16px]"> | ||||||
|  |     <van-pull-refresh | ||||||
|  |         v-model="localState.refreshing" | ||||||
|  |         :success-duration="700" | ||||||
|  |         @refresh="onRefresh" | ||||||
|  |     > | ||||||
|  |       <template #success> | ||||||
|  |         <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |       </template> | ||||||
|  |       <van-list | ||||||
|  |           v-model:loading="storeLoading" | ||||||
|  |           :finished="localState.finished" | ||||||
|  |           :finished-text="$t('home.finished_text')" | ||||||
|  |           @load="loadMore" | ||||||
|  |       > | ||||||
|  |         <div class="w-full flex gap-[16px]"> | ||||||
|  |           <WaterfallFlow :items="displayList"  :column-count="2"> | ||||||
|  |             <template #default="{ item }"> | ||||||
|  |               <div | ||||||
|  |                   @click="openShow(item)" | ||||||
|  |                   class="w-full" | ||||||
|  |               > | ||||||
|  |                 <div class="relative w-full"> | ||||||
|  |                   <!-- 自定义骨架屏 --> | ||||||
|  |                   <div  | ||||||
|  |                     v-if="item.isSkeletonItem || !imageLoadingStatus[item.id]"  | ||||||
|  |                     class="custom-skeleton rounded-4px overflow-hidden" | ||||||
|  |                   > | ||||||
|  |                     <div class="skeleton-image"></div> | ||||||
|  |                     <div class="skeleton-content"> | ||||||
|  |                       <div class="skeleton-title"></div> | ||||||
|  |                       <div class="skeleton-text"></div> | ||||||
|  |                       <div class="skeleton-text"></div> | ||||||
|  |                     </div> | ||||||
|  |                   </div> | ||||||
|  |                    | ||||||
|  |                   <template v-if="!item.isSkeletonItem"> | ||||||
|  |                     <img | ||||||
|  |                         :src="item.artwork?.hdPic" | ||||||
|  |                         class="w-full object-cover rounded-4px" | ||||||
|  |                         :class="{'hidden': !imageLoadingStatus[item.id]}" | ||||||
|  |                         @load="handleImageLoad(item.id)" | ||||||
|  |                         @error="handleImageError(item.id)" | ||||||
|  |                     /> | ||||||
|  |                     <div | ||||||
|  |                         class="absolute rounded-2px overflow-hidden line-height-12px left-[8px] top-[8px] h-[17px] w-[60px] flex items-center justify-center bg-[#2b53ac] text-[12px] text-[#fff]" | ||||||
|  |                         :class="{'z-10': !imageLoadingStatus[item.id]}" | ||||||
|  |                     > | ||||||
|  |                       Lot{{item.index+25000 }} | ||||||
|  |                     </div> | ||||||
|  |                   </template> | ||||||
|  |                 </div> | ||||||
|  |                 <div v-if="!item.isSkeletonItem" class="pt-[8px]" :class="{'hidden': !imageLoadingStatus[item.id]}"> | ||||||
|  |                   <div class="text-[14px] text-[#000000] leading-[20px]"> | ||||||
|  |                     {{ item?.artwork?.name }} | {{item?.artwork?.artistName}} | ||||||
|  |                   </div> | ||||||
|  |                   <div class="mt-[4px] text-[12px] text-[#575757]"> | ||||||
|  |                     {{ $t('home.start_price') }}:{{ item?.startPrice??0 }} | ||||||
|  |                   </div> | ||||||
|  |                   <div | ||||||
|  |                       v-if="item.soldPrice" | ||||||
|  |                       class="mt-[4px] text-[12px] text-[#b58047]" | ||||||
|  |                   > | ||||||
|  |                     {{ $t('home.close_price') }}:{{  item?.soldPrice??0  }} | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </WaterfallFlow> | ||||||
|  |         </div> | ||||||
|  |       </van-list> | ||||||
|  |     </van-pull-refresh> | ||||||
|  |     <DetailPopup v-model:show="localState.showDetail" :detailInfo="currentItem"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .content { | ||||||
|  |   overflow-y: auto; | ||||||
|  |   -webkit-overflow-scrolling: touch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* 自定义骨架屏样式 */ | ||||||
|  | .custom-skeleton { | ||||||
|  |   width: 100%; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   background-color: #fff; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-image { | ||||||
|  |   width: 100%; | ||||||
|  |   padding-bottom: 100%; /* 保持1:1的宽高比 */ | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-content { | ||||||
|  |   padding: 8px 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-title { | ||||||
|  |   height: 16px; | ||||||
|  |   margin-bottom: 8px; | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  |   border-radius: 2px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .skeleton-text { | ||||||
|  |   height: 12px; | ||||||
|  |   margin-top: 4px; | ||||||
|  |   background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%); | ||||||
|  |   background-size: 400% 100%; | ||||||
|  |   animation: skeleton-loading 1.4s ease infinite; | ||||||
|  |   border-radius: 2px; | ||||||
|  |   width: 60%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes skeleton-loading { | ||||||
|  |   0% { | ||||||
|  |     background-position: 100% 50%; | ||||||
|  |   } | ||||||
|  |   100% { | ||||||
|  |     background-position: 0 50%; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										96
									
								
								.history/app/pages/home/index_20250306094955.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								.history/app/pages/home/index_20250306094955.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <ItemList></ItemList> | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										99
									
								
								.history/app/pages/home/index_20250306114651.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								.history/app/pages/home/index_20250306114651.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  | 
 | ||||||
|  |           </div> | ||||||
|  |           <ItemList></ItemList> | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										99
									
								
								.history/app/pages/home/index_20250306114655.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								.history/app/pages/home/index_20250306114655.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										99
									
								
								.history/app/pages/home/index_20250306114938.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								.history/app/pages/home/index_20250306114938.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										99
									
								
								.history/app/pages/home/index_20250306115027.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								.history/app/pages/home/index_20250306115027.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										102
									
								
								.history/app/pages/home/index_20250306115109.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								.history/app/pages/home/index_20250306115109.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,102 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | :deep(.van-tabs.van-tabs--line){ | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										102
									
								
								.history/app/pages/home/index_20250306115149.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								.history/app/pages/home/index_20250306115149.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,102 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | :deep(.van-tabs.van-tabs--line){ | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										102
									
								
								.history/app/pages/home/index_20250306115151.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								.history/app/pages/home/index_20250306115151.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,102 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | :deep(.van-tabs.van-tabs--line){ | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										102
									
								
								.history/app/pages/home/index_20250306115253.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								.history/app/pages/home/index_20250306115253.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,102 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | :deep(.van-tabs.van-tabs--line){ | ||||||
|  |   flex-grow: 1; | ||||||
|  | } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										102
									
								
								.history/app/pages/home/index_20250306115256.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								.history/app/pages/home/index_20250306115256.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,102 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | :deep(.van-tabs.van-tabs--line){ | ||||||
|  |   flex-grow: 1; | ||||||
|  | } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										103
									
								
								.history/app/pages/home/index_20250306115330.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								.history/app/pages/home/index_20250306115330.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | :deep(.van-tabs.van-tabs--line){ | ||||||
|  |   flex-grow: 1; | ||||||
|  |   display: flex; | ||||||
|  | } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										104
									
								
								.history/app/pages/home/index_20250306115336.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								.history/app/pages/home/index_20250306115336.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | :deep(.van-tabs.van-tabs--line){ | ||||||
|  |   flex-grow: 1; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  | } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										107
									
								
								.history/app/pages/home/index_20250306115423.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								.history/app/pages/home/index_20250306115423.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | :deep(.van-tabs.van-tabs--line){ | ||||||
|  |   flex-grow: 1; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  | } | ||||||
|  | :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  |   flex-grow: 1; | ||||||
|  | } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115449.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115449.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | :deep(.van-tabs.van-tabs--line){ | ||||||
|  |   flex-grow: 1; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  | } | ||||||
|  | :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  |   flex-grow: 1; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  | } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115451.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115451.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | :deep(.van-tabs.van-tabs--line){ | ||||||
|  |   flex-grow: 1; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  | } | ||||||
|  | :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  |   flex-grow: 1; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  | } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115547.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115547.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115555.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115555.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red min-h-full"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115559.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115559.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red min-h-full"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115611.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115611.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red min-h-500px"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115635.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115635.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red 600px"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115641.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115641.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red 600px overflow-hidden"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115705.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115705.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red min-h-[600px] overflow-hidden"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115706.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115706.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="bg-red min-h-[600px] overflow-hidden"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115740.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115740.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="min-h-[600px] overflow-hidden"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115742.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115742.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="min-h-[600px] overflow-hidden"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306115809.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306115809.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="min-h-[600px] overflow-hidden"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										109
									
								
								.history/app/pages/home/index_20250306145820.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								.history/app/pages/home/index_20250306145820.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | <script setup> | ||||||
|  | import liveRoom from '@/pages/liveRoom/index.client.vue'; | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import ItemList from './components/ItemList/index.vue' | ||||||
|  | import Cescribe from './components/Cescribe/index.vue' | ||||||
|  | import FloatingBubble from '~/components/floating2/index.vue' | ||||||
|  | 
 | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | const {auctionDetail,getArtworkList,getAuctionDetail} = goodStore(); | ||||||
|  | const {fullLive} = liveStore() | ||||||
|  | const changeLive = () => { | ||||||
|  |   if (!fullLive.value){ | ||||||
|  |     if (auctionDetail.value.isLiving===1){ | ||||||
|  |       fullLive.value = true; | ||||||
|  |       getArtworkList(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | await getAuctionDetail() | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | <template> | ||||||
|  |   <div class="grow-1 flex flex-col"> | ||||||
|  |     <client-only> | ||||||
|  |       <div class="relative" @click="changeLive"> | ||||||
|  |         <liveRoom  :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/> | ||||||
|  |         <div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]"> | ||||||
|  |           <div class="text-18px mb-5px">{{ auctionDetail.title }}</div> | ||||||
|  |           <div class="text-12px mb-54px">{{$t('home.text3')}}{{auctionDetail.isLiving===2?$t('home.text4'):$t('home.text5')}}</div> | ||||||
|  |           <div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div> | ||||||
|  |           <div class="text-12px">{{auctionDetail.startDate}} {{auctionDetail.startTitle}}</div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </client-only> | ||||||
|  |     <div v-if="!fullLive" class="bg-#fff grow-1 flex flex-col"> | ||||||
|  |       <van-tabs sticky animated> | ||||||
|  |         <van-tab :title="$t('home.tab1')"> | ||||||
|  |           <div class="min-h-[600px] overflow-hidden"> | ||||||
|  |             <ItemList></ItemList> | ||||||
|  |           </div> | ||||||
|  |           | ||||||
|  |         </van-tab> | ||||||
|  |         <van-tab :title="$t('home.tab2')"> | ||||||
|  |           <Cescribe></Cescribe> | ||||||
|  |         </van-tab> | ||||||
|  |       </van-tabs> | ||||||
|  |       <van-back-top right="15vw" bottom="10vh"/> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | // :deep(.van-tabs.van-tabs--line){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | // :deep(.van-tabs__content.van-tabs__content--animated){ | ||||||
|  | //   flex-grow: 1; | ||||||
|  | //   display: flex; | ||||||
|  | //   flex-direction: column; | ||||||
|  | // } | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator) { | ||||||
|  |   width: 8px; | ||||||
|  |   height: 8px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 1s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .fade-enter, .fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :deep(.van-swipe__indicator:not(.van-swipe__indicator--active)) { | ||||||
|  |   background: rgba(0, 0, 0, 0.8); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive { | ||||||
|  |   width: 100%; | ||||||
|  |   overflow: hidden; | ||||||
|  |   transition: height 0.4s ease, transform 0.4s ease; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.collapsed { | ||||||
|  |   height: 188px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .changeLive.expanded { | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: 10; | ||||||
|  |   height: calc(100vh - var(--van-nav-bar-height)); | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,154 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,(newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,157 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,(newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |           class="container" | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |           <van-back-top target=".container" bottom="30vh" /> | ||||||
|  | 
 | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,157 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,(newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |           class="container" | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |           <van-back-top target=".container" bottom="30vh" /> | ||||||
|  | 
 | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,154 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,(newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,195 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '', | ||||||
|  |   isSearchingCurrentItem: false | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = async () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |    | ||||||
|  |   const targetIndex = auctionData.value.artwork.index | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => targetIndex === item?.index | ||||||
|  |   ) | ||||||
|  |    | ||||||
|  |   if (currentIndex === -1) { | ||||||
|  |     try { | ||||||
|  |       localState.value.isSearchingCurrentItem = true | ||||||
|  |        | ||||||
|  |       const originalPageSize = pageRef.value.pageSize | ||||||
|  |       pageRef.value.pageSize = 20 | ||||||
|  |       pageRef.value.page = 1 | ||||||
|  |        | ||||||
|  |       await getArtworkList(true) | ||||||
|  |        | ||||||
|  |       pageRef.value.pageSize = originalPageSize | ||||||
|  |        | ||||||
|  |       const newIndex = itemList.value.findIndex( | ||||||
|  |         item => targetIndex === item?.index | ||||||
|  |       ) | ||||||
|  |        | ||||||
|  |       if (newIndex > -1) { | ||||||
|  |         nextTick(() => { | ||||||
|  |           scrollToElement(newIndex) | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |     } finally { | ||||||
|  |       localState.value.isSearchingCurrentItem = false | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     scrollToElement(currentIndex) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const scrollToElement = (index) => { | ||||||
|  |   const container = document.querySelector('.list-container') | ||||||
|  |   const targetElement = document.querySelectorAll('.item-wrapper')[index] | ||||||
|  |   if (targetElement && container) { | ||||||
|  |     const containerTop = container.getBoundingClientRect().top | ||||||
|  |     const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |     const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |     container.scrollTo({ | ||||||
|  |       top: scrollTop, | ||||||
|  |       behavior: 'smooth' | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,(newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <div v-if="localState.isSearchingCurrentItem" class="searching-item-tip"> | ||||||
|  |             {{ $t('live_room.searching_current_lot') || '正在查找当前拍品...' }} | ||||||
|  |           </div> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  |               class="list-container" | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .searching-item-tip { | ||||||
|  |   text-align: center; | ||||||
|  |   padding: 10px 0; | ||||||
|  |   color: #B58047; | ||||||
|  |   font-size: 14px; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,236 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '', | ||||||
|  |   isSearchingCurrentItem: false | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = async () => { | ||||||
|  |   if (!auctionData.value?.artwork?.index) return | ||||||
|  |    | ||||||
|  |   const targetIndex = auctionData.value.artwork.index | ||||||
|  |   let currentIndex = itemList.value.findIndex(item => targetIndex === item?.index) | ||||||
|  |    | ||||||
|  |   if (currentIndex === -1) { | ||||||
|  |     try { | ||||||
|  |       localState.value.isSearchingCurrentItem = true | ||||||
|  |        | ||||||
|  |       await searchSpecificItem(targetIndex) | ||||||
|  |        | ||||||
|  |       currentIndex = itemList.value.findIndex(item => targetIndex === item?.index) | ||||||
|  |        | ||||||
|  |       if (currentIndex > -1) { | ||||||
|  |         await nextTick() | ||||||
|  |         scrollToElement(currentIndex) | ||||||
|  |       } | ||||||
|  |     } finally { | ||||||
|  |       localState.value.isSearchingCurrentItem = false | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     await nextTick() | ||||||
|  |     scrollToElement(currentIndex) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const searchSpecificItem = async (targetIndex) => { | ||||||
|  |   try { | ||||||
|  |     const originalPage = pageRef.value.page | ||||||
|  |     const originalPageSize = pageRef.value.pageSize | ||||||
|  |      | ||||||
|  |     const estimatedPage = Math.ceil(targetIndex / 20) | ||||||
|  |      | ||||||
|  |     pageRef.value.pageSize = 50 | ||||||
|  |      | ||||||
|  |     pageRef.value.page = estimatedPage > 0 ? estimatedPage : 1 | ||||||
|  |     await getArtworkList(true) | ||||||
|  |      | ||||||
|  |     let found = itemList.value.some(item => targetIndex === item?.index) | ||||||
|  |      | ||||||
|  |     if (!found) { | ||||||
|  |       pageRef.value.page = 1 | ||||||
|  |       pageRef.value.pageSize = 100 | ||||||
|  |       await getArtworkList(true) | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     pageRef.value.page = originalPage | ||||||
|  |     pageRef.value.pageSize = originalPageSize | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error('搜索特定拍品时出错:', error) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const scrollToElement = (index) => { | ||||||
|  |   const container = document.querySelector('.list-container') | ||||||
|  |   const allItems = document.querySelectorAll('.item-wrapper') | ||||||
|  |    | ||||||
|  |   if (!container || !allItems.length || index >= allItems.length) { | ||||||
|  |     console.warn('无法滚动:容器或目标元素不存在') | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   const targetElement = allItems[index] | ||||||
|  |    | ||||||
|  |   if (targetElement) { | ||||||
|  |     const containerRect = container.getBoundingClientRect() | ||||||
|  |     const elementRect = targetElement.getBoundingClientRect() | ||||||
|  |      | ||||||
|  |     const scrollTop = elementRect.top - containerRect.top + container.scrollTop | ||||||
|  |      | ||||||
|  |     container.scrollTo({ | ||||||
|  |       top: Math.max(0, scrollTop - 20), | ||||||
|  |       behavior: 'smooth' | ||||||
|  |     }) | ||||||
|  |      | ||||||
|  |     targetElement.classList.add('highlight-item') | ||||||
|  |     setTimeout(() => { | ||||||
|  |       targetElement.classList.remove('highlight-item') | ||||||
|  |     }, 2000) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,(newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <div v-if="localState.isSearchingCurrentItem" class="searching-item-tip"> | ||||||
|  |             {{ $t('live_room.searching_current_lot') || '正在查找当前拍品...' }} | ||||||
|  |           </div> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  |               class="list-container" | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .searching-item-tip { | ||||||
|  |   text-align: center; | ||||||
|  |   padding: 10px 0; | ||||||
|  |   color: #B58047; | ||||||
|  |   font-size: 14px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highlight-item { | ||||||
|  |   animation: highlight-pulse 2s ease-in-out; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes highlight-pulse { | ||||||
|  |   0% { box-shadow: 0 0 0 0 rgba(181, 128, 71, 0.7); } | ||||||
|  |   50% { box-shadow: 0 0 0 10px rgba(181, 128, 71, 0); } | ||||||
|  |   100% { box-shadow: 0 0 0 0 rgba(181, 128, 71, 0); } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,331 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref, nextTick, watch, onMounted} from "vue"; | ||||||
|  | 
 | ||||||
|  | const {pageRef, itemList, getArtworkList, loading: storeLoading} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail = ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '', | ||||||
|  |   isSearchingCurrentItem: false, | ||||||
|  |   debugInfo: ''  // 添加调试信息字段 | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // DOM引用 | ||||||
|  | const listContainerRef = ref(null) | ||||||
|  | 
 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 设置调试信息的辅助函数 | ||||||
|  | const setDebugInfo = (info) => { | ||||||
|  |   console.log('调试信息:', info) | ||||||
|  |   localState.value.debugInfo = info | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 增强版的滚动到当前拍品函数 | ||||||
|  | const scrollToCurrentItem = async () => { | ||||||
|  |   if (!auctionData.value?.artwork?.index) { | ||||||
|  |     setDebugInfo('当前拍品索引不存在') | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   const targetIndex = auctionData.value.artwork.index | ||||||
|  |   setDebugInfo(`开始查找目标拍品: LOT${targetIndex}`) | ||||||
|  |    | ||||||
|  |   let currentIndex = itemList.value.findIndex(item => targetIndex === item?.index) | ||||||
|  |    | ||||||
|  |   if (currentIndex === -1) { | ||||||
|  |     try { | ||||||
|  |       localState.value.isSearchingCurrentItem = true | ||||||
|  |       setDebugInfo(`当前列表中未找到目标拍品,开始加载更多数据...`) | ||||||
|  |        | ||||||
|  |       // 尝试搜索特定拍品 | ||||||
|  |       await searchSpecificItem(targetIndex) | ||||||
|  |        | ||||||
|  |       // 检查是否找到了 | ||||||
|  |       currentIndex = itemList.value.findIndex(item => targetIndex === item?.index) | ||||||
|  |       setDebugInfo(`加载数据后,拍品索引位置: ${currentIndex}`) | ||||||
|  |        | ||||||
|  |       if (currentIndex > -1) { | ||||||
|  |         // 等待列表渲染完成 | ||||||
|  |         await new Promise(resolve => setTimeout(resolve, 300)) | ||||||
|  |         await nextTick() | ||||||
|  |         scrollToElement(currentIndex) | ||||||
|  |       } else { | ||||||
|  |         setDebugInfo(`加载后仍未找到目标拍品 LOT${targetIndex}`) | ||||||
|  |       } | ||||||
|  |     } finally { | ||||||
|  |       localState.value.isSearchingCurrentItem = false | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     setDebugInfo(`在现有列表中找到拍品,位置: ${currentIndex}`) | ||||||
|  |     // 等待列表渲染完成 | ||||||
|  |     await new Promise(resolve => setTimeout(resolve, 300)) | ||||||
|  |     await nextTick() | ||||||
|  |     scrollToElement(currentIndex) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 搜索特定拍品的优化函数 | ||||||
|  | const searchSpecificItem = async (targetIndex) => { | ||||||
|  |   try { | ||||||
|  |     // 保存原始设置 | ||||||
|  |     const originalPage = pageRef.value.page | ||||||
|  |     const originalPageSize = pageRef.value.pageSize | ||||||
|  |      | ||||||
|  |     setDebugInfo(`尝试使用更大页面大小搜索拍品LOT${targetIndex}`) | ||||||
|  |      | ||||||
|  |     // 策略1: 直接设置大页面大小加载首页数据 | ||||||
|  |     pageRef.value.page = 1 | ||||||
|  |     pageRef.value.pageSize = 100 // 使用较大的页面大小 | ||||||
|  |     await getArtworkList(true) | ||||||
|  |      | ||||||
|  |     // 检查是否找到 | ||||||
|  |     let found = itemList.value.some(item => targetIndex === item?.index) | ||||||
|  |     setDebugInfo(`策略1结果: ${found ? '找到' : '未找到'}`) | ||||||
|  |      | ||||||
|  |     // 策略2: 如果没找到,尝试基于目标索引估算页码 | ||||||
|  |     if (!found) { | ||||||
|  |       // 估算目标页面 (假设每页20个拍品) | ||||||
|  |       const estimatedPage = Math.ceil(targetIndex / 10) | ||||||
|  |       setDebugInfo(`尝试策略2: 估算页码 ${estimatedPage}`) | ||||||
|  |        | ||||||
|  |       pageRef.value.page = estimatedPage > 0 ? estimatedPage : 1 | ||||||
|  |       await getArtworkList(true) | ||||||
|  |        | ||||||
|  |       found = itemList.value.some(item => targetIndex === item?.index) | ||||||
|  |       setDebugInfo(`策略2结果: ${found ? '找到' : '未找到'}`) | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // 恢复原始设置 | ||||||
|  |     pageRef.value.page = originalPage | ||||||
|  |     pageRef.value.pageSize = originalPageSize | ||||||
|  |      | ||||||
|  |     return found | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error('搜索特定拍品时出错:', error) | ||||||
|  |     setDebugInfo(`搜索出错: ${error.message}`) | ||||||
|  |     return false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 改进滚动到元素的函数 | ||||||
|  | const scrollToElement = (index) => { | ||||||
|  |   setDebugInfo(`尝试滚动到元素 index=${index}`) | ||||||
|  |    | ||||||
|  |   // 获取容器和目标元素 | ||||||
|  |   const allItems = document.querySelectorAll('.item-wrapper') | ||||||
|  |    | ||||||
|  |   if (!listContainerRef.value || !allItems.length || index >= allItems.length) { | ||||||
|  |     setDebugInfo(`无法滚动: 容器或元素不存在 (找到${allItems.length}个元素)`) | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   const targetElement = allItems[index] | ||||||
|  |   const container = listContainerRef.value | ||||||
|  |    | ||||||
|  |   if (targetElement && container) { | ||||||
|  |     try { | ||||||
|  |       setDebugInfo(`找到目标元素和容器,执行滚动`) | ||||||
|  |        | ||||||
|  |       // 使用 Element.scrollIntoView 更可靠的滚动方法 | ||||||
|  |       targetElement.scrollIntoView({ | ||||||
|  |         behavior: 'smooth', | ||||||
|  |         block: 'center' | ||||||
|  |       }) | ||||||
|  |        | ||||||
|  |       // 添加高亮效果 | ||||||
|  |       targetElement.classList.add('highlight-item') | ||||||
|  |       setTimeout(() => { | ||||||
|  |         targetElement.classList.remove('highlight-item') | ||||||
|  |       }, 2000) | ||||||
|  |        | ||||||
|  |       setDebugInfo(`滚动完成并应用高亮效果`) | ||||||
|  |     } catch (error) { | ||||||
|  |       setDebugInfo(`滚动过程出错: ${error.message}`) | ||||||
|  |       console.error('滚动过程出错:', error) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo = ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow = (item) => { | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 监听拍品变化 | ||||||
|  | watch(() => auctionData.value?.artwork?.index, (newValue, oldValue) => { | ||||||
|  |   if (newValue && newValue !== oldValue && props.show) { | ||||||
|  |     setDebugInfo(`检测到拍品索引变化: ${oldValue} -> ${newValue}`) | ||||||
|  |     nextTick(() => { | ||||||
|  |       scrollToCurrentItem() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 监听弹窗显示状态 | ||||||
|  | watch(() => props.show, (newValue) => { | ||||||
|  |   if (newValue) { | ||||||
|  |     setDebugInfo('弹窗显示,准备滚动到当前拍品') | ||||||
|  |     // 延迟执行,确保DOM已渲染 | ||||||
|  |     setTimeout(() => { | ||||||
|  |       scrollToCurrentItem() | ||||||
|  |     }, 500) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |            | ||||||
|  |           <!-- 搜索提示 --> | ||||||
|  |           <div v-if="localState.isSearchingCurrentItem" class="searching-item-tip"> | ||||||
|  |             {{ $t('live_room.searching_current_lot') || '正在查找当前拍品...' }} | ||||||
|  |           </div> | ||||||
|  |            | ||||||
|  |           <!-- 调试信息区域,可在生产环境中移除 --> | ||||||
|  |           <div v-if="localState.debugInfo" class="debug-info"> | ||||||
|  |             {{ localState.debugInfo }} | ||||||
|  |           </div> | ||||||
|  |            | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  |               class="list-container" | ||||||
|  |               ref="listContainerRef" | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |                 :class="{'current-item': auctionData?.artwork?.index === item?.index}" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .searching-item-tip { | ||||||
|  |   text-align: center; | ||||||
|  |   padding: 10px 0; | ||||||
|  |   color: #B58047; | ||||||
|  |   font-size: 14px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highlight-item { | ||||||
|  |   animation: highlight-pulse 2s ease-in-out; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes highlight-pulse { | ||||||
|  |   0% { box-shadow: 0 0 0 0 rgba(181, 128, 71, 0.7); } | ||||||
|  |   50% { box-shadow: 0 0 0 10px rgba(181, 128, 71, 0); } | ||||||
|  |   100% { box-shadow: 0 0 0 0 rgba(181, 128, 71, 0); } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .current-item { | ||||||
|  |   background-color: rgba(181, 128, 71, 0.1); | ||||||
|  |   border-radius: 4px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .debug-info { | ||||||
|  |   padding: 8px; | ||||||
|  |   background-color: #f5f5f5; | ||||||
|  |   border: 1px solid #ddd; | ||||||
|  |   color: #333; | ||||||
|  |   font-size: 12px; | ||||||
|  |   margin: 5px 0; | ||||||
|  |   word-break: break-all; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,331 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref, nextTick, watch, onMounted} from "vue"; | ||||||
|  | 
 | ||||||
|  | const {pageRef, itemList, getArtworkList, loading: storeLoading} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail = ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '', | ||||||
|  |   isSearchingCurrentItem: false, | ||||||
|  |   debugInfo: ''  // 添加调试信息字段 | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // DOM引用 | ||||||
|  | const listContainerRef = ref(null) | ||||||
|  | 
 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 设置调试信息的辅助函数 | ||||||
|  | const setDebugInfo = (info) => { | ||||||
|  |   console.log('调试信息:', info) | ||||||
|  |   localState.value.debugInfo = info | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 增强版的滚动到当前拍品函数 | ||||||
|  | const scrollToCurrentItem = async () => { | ||||||
|  |   if (!auctionData.value?.artwork?.index) { | ||||||
|  |     setDebugInfo('当前拍品索引不存在') | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   const targetIndex = auctionData.value.artwork.index | ||||||
|  |   setDebugInfo(`开始查找目标拍品: LOT${targetIndex}`) | ||||||
|  |    | ||||||
|  |   let currentIndex = itemList.value.findIndex(item => targetIndex === item?.index) | ||||||
|  |    | ||||||
|  |   if (currentIndex === -1) { | ||||||
|  |     try { | ||||||
|  |       localState.value.isSearchingCurrentItem = true | ||||||
|  |       setDebugInfo(`当前列表中未找到目标拍品,开始加载更多数据...`) | ||||||
|  |        | ||||||
|  |       // 尝试搜索特定拍品 | ||||||
|  |       await searchSpecificItem(targetIndex) | ||||||
|  |        | ||||||
|  |       // 检查是否找到了 | ||||||
|  |       currentIndex = itemList.value.findIndex(item => targetIndex === item?.index) | ||||||
|  |       setDebugInfo(`加载数据后,拍品索引位置: ${currentIndex}`) | ||||||
|  |        | ||||||
|  |       if (currentIndex > -1) { | ||||||
|  |         // 等待列表渲染完成 | ||||||
|  |         await new Promise(resolve => setTimeout(resolve, 300)) | ||||||
|  |         await nextTick() | ||||||
|  |         scrollToElement(currentIndex) | ||||||
|  |       } else { | ||||||
|  |         setDebugInfo(`加载后仍未找到目标拍品 LOT${targetIndex}`) | ||||||
|  |       } | ||||||
|  |     } finally { | ||||||
|  |       localState.value.isSearchingCurrentItem = false | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     setDebugInfo(`在现有列表中找到拍品,位置: ${currentIndex}`) | ||||||
|  |     // 等待列表渲染完成 | ||||||
|  |     await new Promise(resolve => setTimeout(resolve, 300)) | ||||||
|  |     await nextTick() | ||||||
|  |     scrollToElement(currentIndex) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 搜索特定拍品的优化函数 | ||||||
|  | const searchSpecificItem = async (targetIndex) => { | ||||||
|  |   try { | ||||||
|  |     // 保存原始设置 | ||||||
|  |     const originalPage = pageRef.value.page | ||||||
|  |     const originalPageSize = pageRef.value.pageSize | ||||||
|  |      | ||||||
|  |     setDebugInfo(`尝试使用更大页面大小搜索拍品LOT${targetIndex}`) | ||||||
|  |      | ||||||
|  |     // 策略1: 直接设置大页面大小加载首页数据 | ||||||
|  |     pageRef.value.page = 1 | ||||||
|  |     pageRef.value.pageSize = 100 // 使用较大的页面大小 | ||||||
|  |     await getArtworkList(true) | ||||||
|  |      | ||||||
|  |     // 检查是否找到 | ||||||
|  |     let found = itemList.value.some(item => targetIndex === item?.index) | ||||||
|  |     setDebugInfo(`策略1结果: ${found ? '找到' : '未找到'}`) | ||||||
|  |      | ||||||
|  |     // 策略2: 如果没找到,尝试基于目标索引估算页码 | ||||||
|  |     if (!found) { | ||||||
|  |       // 估算目标页面 (假设每页20个拍品) | ||||||
|  |       const estimatedPage = Math.ceil(targetIndex / 10) | ||||||
|  |       setDebugInfo(`尝试策略2: 估算页码 ${estimatedPage}`) | ||||||
|  |        | ||||||
|  |       pageRef.value.page = estimatedPage > 0 ? estimatedPage : 1 | ||||||
|  |       await getArtworkList(true) | ||||||
|  |        | ||||||
|  |       found = itemList.value.some(item => targetIndex === item?.index) | ||||||
|  |       setDebugInfo(`策略2结果: ${found ? '找到' : '未找到'}`) | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // 恢复原始设置 | ||||||
|  |     pageRef.value.page = originalPage | ||||||
|  |     pageRef.value.pageSize = originalPageSize | ||||||
|  |      | ||||||
|  |     return found | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error('搜索特定拍品时出错:', error) | ||||||
|  |     setDebugInfo(`搜索出错: ${error.message}`) | ||||||
|  |     return false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 改进滚动到元素的函数 | ||||||
|  | const scrollToElement = (index) => { | ||||||
|  |   setDebugInfo(`尝试滚动到元素 index=${index}`) | ||||||
|  |    | ||||||
|  |   // 获取容器和目标元素 | ||||||
|  |   const allItems = document.querySelectorAll('.item-wrapper') | ||||||
|  |    | ||||||
|  |   if (!listContainerRef.value || !allItems.length || index >= allItems.length) { | ||||||
|  |     setDebugInfo(`无法滚动: 容器或元素不存在 (找到${allItems.length}个元素)`) | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   const targetElement = allItems[index] | ||||||
|  |   const container = listContainerRef.value | ||||||
|  |    | ||||||
|  |   if (targetElement && container) { | ||||||
|  |     try { | ||||||
|  |       setDebugInfo(`找到目标元素和容器,执行滚动`) | ||||||
|  |        | ||||||
|  |       // 使用 Element.scrollIntoView 更可靠的滚动方法 | ||||||
|  |       targetElement.scrollIntoView({ | ||||||
|  |         behavior: 'smooth', | ||||||
|  |         block: 'center' | ||||||
|  |       }) | ||||||
|  |        | ||||||
|  |       // 添加高亮效果 | ||||||
|  |       targetElement.classList.add('highlight-item') | ||||||
|  |       setTimeout(() => { | ||||||
|  |         targetElement.classList.remove('highlight-item') | ||||||
|  |       }, 2000) | ||||||
|  |        | ||||||
|  |       setDebugInfo(`滚动完成并应用高亮效果`) | ||||||
|  |     } catch (error) { | ||||||
|  |       setDebugInfo(`滚动过程出错: ${error.message}`) | ||||||
|  |       console.error('滚动过程出错:', error) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo = ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow = (item) => { | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 监听拍品变化 | ||||||
|  | watch(() => auctionData.value?.artwork?.index, (newValue, oldValue) => { | ||||||
|  |   if (newValue && newValue !== oldValue && props.show) { | ||||||
|  |     setDebugInfo(`检测到拍品索引变化: ${oldValue} -> ${newValue}`) | ||||||
|  |     nextTick(() => { | ||||||
|  |       scrollToCurrentItem() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 监听弹窗显示状态 | ||||||
|  | watch(() => props.show, (newValue) => { | ||||||
|  |   if (newValue) { | ||||||
|  |     setDebugInfo('弹窗显示,准备滚动到当前拍品') | ||||||
|  |     // 延迟执行,确保DOM已渲染 | ||||||
|  |     setTimeout(() => { | ||||||
|  |       scrollToCurrentItem() | ||||||
|  |     }, 500) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |            | ||||||
|  |           <!-- 搜索提示 --> | ||||||
|  |           <div v-if="localState.isSearchingCurrentItem" class="searching-item-tip"> | ||||||
|  |             {{ $t('live_room.searching_current_lot') || '正在查找当前拍品...' }} | ||||||
|  |           </div> | ||||||
|  |            | ||||||
|  |           <!-- 调试信息区域,可在生产环境中移除 --> | ||||||
|  |           <div v-if="localState.debugInfo" class="debug-info"> | ||||||
|  |             {{ localState.debugInfo }} | ||||||
|  |           </div> | ||||||
|  |            | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  |               class="list-container" | ||||||
|  |               ref="listContainerRef" | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |                 :class="{'current-item': auctionData?.artwork?.index === item?.index}" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .searching-item-tip { | ||||||
|  |   text-align: center; | ||||||
|  |   padding: 10px 0; | ||||||
|  |   color: #B58047; | ||||||
|  |   font-size: 14px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highlight-item { | ||||||
|  |   animation: highlight-pulse 2s ease-in-out; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes highlight-pulse { | ||||||
|  |   0% { box-shadow: 0 0 0 0 rgba(181, 128, 71, 0.7); } | ||||||
|  |   50% { box-shadow: 0 0 0 10px rgba(181, 128, 71, 0); } | ||||||
|  |   100% { box-shadow: 0 0 0 0 rgba(181, 128, 71, 0); } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .current-item { | ||||||
|  |   background-color: rgba(181, 128, 71, 0.1); | ||||||
|  |   border-radius: 4px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .debug-info { | ||||||
|  |   padding: 8px; | ||||||
|  |   background-color: #f5f5f5; | ||||||
|  |   border: 1px solid #ddd; | ||||||
|  |   color: #333; | ||||||
|  |   font-size: 12px; | ||||||
|  |   margin: 5px 0; | ||||||
|  |   word-break: break-all; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,331 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref, nextTick, watch, onMounted} from "vue"; | ||||||
|  | 
 | ||||||
|  | const {pageRef, itemList, getArtworkList, loading: storeLoading} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail = ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '', | ||||||
|  |   isSearchingCurrentItem: false, | ||||||
|  |   debugInfo: ''  // 添加调试信息字段 | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // DOM引用 | ||||||
|  | const listContainerRef = ref(null) | ||||||
|  | 
 | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 设置调试信息的辅助函数 | ||||||
|  | const setDebugInfo = (info) => { | ||||||
|  |   console.log('调试信息:', info) | ||||||
|  |   localState.value.debugInfo = info | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 增强版的滚动到当前拍品函数 | ||||||
|  | const scrollToCurrentItem = async () => { | ||||||
|  |   if (!auctionData.value?.artwork?.index) { | ||||||
|  |     setDebugInfo('当前拍品索引不存在') | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   const targetIndex = auctionData.value.artwork.index | ||||||
|  |   setDebugInfo(`开始查找目标拍品: LOT${targetIndex}`) | ||||||
|  |    | ||||||
|  |   let currentIndex = itemList.value.findIndex(item => targetIndex === item?.index) | ||||||
|  |    | ||||||
|  |   if (currentIndex === -1) { | ||||||
|  |     try { | ||||||
|  |       localState.value.isSearchingCurrentItem = true | ||||||
|  |       setDebugInfo(`当前列表中未找到目标拍品,开始加载更多数据...`) | ||||||
|  |        | ||||||
|  |       // 尝试搜索特定拍品 | ||||||
|  |       await searchSpecificItem(targetIndex) | ||||||
|  |        | ||||||
|  |       // 检查是否找到了 | ||||||
|  |       currentIndex = itemList.value.findIndex(item => targetIndex === item?.index) | ||||||
|  |       setDebugInfo(`加载数据后,拍品索引位置: ${currentIndex}`) | ||||||
|  |        | ||||||
|  |       if (currentIndex > -1) { | ||||||
|  |         // 等待列表渲染完成 | ||||||
|  |         await new Promise(resolve => setTimeout(resolve, 300)) | ||||||
|  |         await nextTick() | ||||||
|  |         scrollToElement(currentIndex) | ||||||
|  |       } else { | ||||||
|  |         setDebugInfo(`加载后仍未找到目标拍品 LOT${targetIndex}`) | ||||||
|  |       } | ||||||
|  |     } finally { | ||||||
|  |       localState.value.isSearchingCurrentItem = false | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     setDebugInfo(`在现有列表中找到拍品,位置: ${currentIndex}`) | ||||||
|  |     // 等待列表渲染完成 | ||||||
|  |     await new Promise(resolve => setTimeout(resolve, 300)) | ||||||
|  |     await nextTick() | ||||||
|  |     scrollToElement(currentIndex) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 搜索特定拍品的优化函数 | ||||||
|  | const searchSpecificItem = async (targetIndex) => { | ||||||
|  |   try { | ||||||
|  |     // 保存原始设置 | ||||||
|  |     const originalPage = pageRef.value.page | ||||||
|  |     const originalPageSize = pageRef.value.pageSize | ||||||
|  |      | ||||||
|  |     setDebugInfo(`尝试使用更大页面大小搜索拍品LOT${targetIndex}`) | ||||||
|  |      | ||||||
|  |     // 策略1: 直接设置大页面大小加载首页数据 | ||||||
|  |     pageRef.value.page = 1 | ||||||
|  |     pageRef.value.pageSize = 100 // 使用较大的页面大小 | ||||||
|  |     await getArtworkList(true) | ||||||
|  |      | ||||||
|  |     // 检查是否找到 | ||||||
|  |     let found = itemList.value.some(item => targetIndex === item?.index) | ||||||
|  |     setDebugInfo(`策略1结果: ${found ? '找到' : '未找到'}`) | ||||||
|  |      | ||||||
|  |     // 策略2: 如果没找到,尝试基于目标索引估算页码 | ||||||
|  |     if (!found) { | ||||||
|  |       // 估算目标页面 (假设每页20个拍品) | ||||||
|  |       const estimatedPage = Math.ceil(targetIndex / 10) | ||||||
|  |       setDebugInfo(`尝试策略2: 估算页码 ${estimatedPage}`) | ||||||
|  |        | ||||||
|  |       pageRef.value.page = estimatedPage > 0 ? estimatedPage : 1 | ||||||
|  |       await getArtworkList(true) | ||||||
|  |        | ||||||
|  |       found = itemList.value.some(item => targetIndex === item?.index) | ||||||
|  |       setDebugInfo(`策略2结果: ${found ? '找到' : '未找到'}`) | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // 恢复原始设置 | ||||||
|  |     pageRef.value.page = originalPage | ||||||
|  |     pageRef.value.pageSize = originalPageSize | ||||||
|  |      | ||||||
|  |     return found | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error('搜索特定拍品时出错:', error) | ||||||
|  |     setDebugInfo(`搜索出错: ${error.message}`) | ||||||
|  |     return false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 改进滚动到元素的函数 | ||||||
|  | const scrollToElement = (index) => { | ||||||
|  |   setDebugInfo(`尝试滚动到元素 index=${index}`) | ||||||
|  |    | ||||||
|  |   // 获取容器和目标元素 | ||||||
|  |   const allItems = document.querySelectorAll('.item-wrapper') | ||||||
|  |    | ||||||
|  |   if (!listContainerRef.value || !allItems.length || index >= allItems.length) { | ||||||
|  |     setDebugInfo(`无法滚动: 容器或元素不存在 (找到${allItems.length}个元素)`) | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   const targetElement = allItems[index] | ||||||
|  |   const container = listContainerRef.value | ||||||
|  |    | ||||||
|  |   if (targetElement && container) { | ||||||
|  |     try { | ||||||
|  |       setDebugInfo(`找到目标元素和容器,执行滚动`) | ||||||
|  |        | ||||||
|  |       // 使用 Element.scrollIntoView 更可靠的滚动方法 | ||||||
|  |       targetElement.scrollIntoView({ | ||||||
|  |         behavior: 'smooth', | ||||||
|  |         block: 'center' | ||||||
|  |       }) | ||||||
|  |        | ||||||
|  |       // 添加高亮效果 | ||||||
|  |       targetElement.classList.add('highlight-item') | ||||||
|  |       setTimeout(() => { | ||||||
|  |         targetElement.classList.remove('highlight-item') | ||||||
|  |       }, 2000) | ||||||
|  |        | ||||||
|  |       setDebugInfo(`滚动完成并应用高亮效果`) | ||||||
|  |     } catch (error) { | ||||||
|  |       setDebugInfo(`滚动过程出错: ${error.message}`) | ||||||
|  |       console.error('滚动过程出错:', error) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo = ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow = (item) => { | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 监听拍品变化 | ||||||
|  | watch(() => auctionData.value?.artwork?.index, (newValue, oldValue) => { | ||||||
|  |   if (newValue && newValue !== oldValue && props.show) { | ||||||
|  |     setDebugInfo(`检测到拍品索引变化: ${oldValue} -> ${newValue}`) | ||||||
|  |     nextTick(() => { | ||||||
|  |       scrollToCurrentItem() | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 监听弹窗显示状态 | ||||||
|  | watch(() => props.show, (newValue) => { | ||||||
|  |   if (newValue) { | ||||||
|  |     setDebugInfo('弹窗显示,准备滚动到当前拍品') | ||||||
|  |     // 延迟执行,确保DOM已渲染 | ||||||
|  |     setTimeout(() => { | ||||||
|  |       scrollToCurrentItem() | ||||||
|  |     }, 500) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |            | ||||||
|  |           <!-- 搜索提示 --> | ||||||
|  |           <div v-if="localState.isSearchingCurrentItem" class="searching-item-tip"> | ||||||
|  |             {{ $t('live_room.searching_current_lot') || '正在查找当前拍品...' }} | ||||||
|  |           </div> | ||||||
|  |            | ||||||
|  |           <!-- 调试信息区域,可在生产环境中移除 --> | ||||||
|  |           <div v-if="localState.debugInfo" class="debug-info"> | ||||||
|  |             {{ localState.debugInfo }} | ||||||
|  |           </div> | ||||||
|  |            | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  |               class="list-container" | ||||||
|  |               ref="listContainerRef" | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |                 :class="{'current-item': auctionData?.artwork?.index === item?.index}" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .searching-item-tip { | ||||||
|  |   text-align: center; | ||||||
|  |   padding: 10px 0; | ||||||
|  |   color: #B58047; | ||||||
|  |   font-size: 14px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .highlight-item { | ||||||
|  |   animation: highlight-pulse 2s ease-in-out; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes highlight-pulse { | ||||||
|  |   0% { box-shadow: 0 0 0 0 rgba(181, 128, 71, 0.7); } | ||||||
|  |   50% { box-shadow: 0 0 0 10px rgba(181, 128, 71, 0); } | ||||||
|  |   100% { box-shadow: 0 0 0 0 rgba(181, 128, 71, 0); } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .current-item { | ||||||
|  |   background-color: rgba(181, 128, 71, 0.1); | ||||||
|  |   border-radius: 4px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .debug-info { | ||||||
|  |   padding: 8px; | ||||||
|  |   background-color: #f5f5f5; | ||||||
|  |   border: 1px solid #ddd; | ||||||
|  |   color: #333; | ||||||
|  |   font-size: 12px; | ||||||
|  |   margin: 5px 0; | ||||||
|  |   word-break: break-all; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,154 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,(newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,154 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,(newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,155 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,(newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |      | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,158 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,async (newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |     if(auctionData.value?.artwork?.index>itemList.value?.length+1){ | ||||||
|  |       pageRef.value.pageSize=auctionData.value?.artwork?.index-itemList.value?.length | ||||||
|  |      await loadMore() | ||||||
|  |     } | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,158 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,async (newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |     if(auctionData.value?.artwork?.index>itemList.value?.length+1){ | ||||||
|  |       pageRef.value.pageSize=auctionData.value?.artwork?.index-itemList.value?.length | ||||||
|  |      await loadMore() | ||||||
|  |     } | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,159 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,async (newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |     if(auctionData.value?.artwork?.index>itemList.value?.length+1){ | ||||||
|  |       pageRef.value.pageSize=auctionData.value?.artwork?.index-itemList.value?.length | ||||||
|  |      await loadMore() | ||||||
|  |      pageRef.value.pageSize=5 | ||||||
|  |     } | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,159 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,async (newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |     if(auctionData.value?.artwork?.index>itemList.value?.length+1){ | ||||||
|  |       pageRef.value.pageSize=auctionData.value?.artwork?.index-itemList.value?.length | ||||||
|  |      await loadMore() | ||||||
|  |      pageRef.value.pageSize=5 | ||||||
|  |     } | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,165 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |       toast.close() | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,async (newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |     if(auctionData.value?.artwork?.index>itemList.value?.length+1){ | ||||||
|  |       const toast = showLoadingToast({ | ||||||
|  |   message: '加载中...', | ||||||
|  |   forbidClick: true, | ||||||
|  | }); | ||||||
|  |       pageRef.value.pageSize=auctionData.value?.artwork?.index-itemList.value?.length | ||||||
|  |      await loadMore() | ||||||
|  |       | ||||||
|  |      pageRef.value.pageSize=5 | ||||||
|  |     } | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -0,0 +1,165 @@ | |||||||
|  | <script setup> | ||||||
|  | import xPopup from '@/components/x-popup/index.vue' | ||||||
|  | import {goodStore} from "@/stores/goods/index.js"; | ||||||
|  | import xImage from '@/components/x-image/index.vue' | ||||||
|  | import DetailPopup from '@/pages/home/components/DetailPopup/index.vue' | ||||||
|  | import {liveStore} from "~/stores/live/index.js"; | ||||||
|  | import {ref} from "vue"; | ||||||
|  | const {pageRef,itemList,getArtworkList,  loading: storeLoading,} = goodStore(); | ||||||
|  | const {auctionData} = liveStore() | ||||||
|  | const showDetail=ref(false) | ||||||
|  | const localState = ref({ | ||||||
|  |   finished: false, | ||||||
|  |   refreshing: false, | ||||||
|  |   showDetail: false, | ||||||
|  |   showHeight: '' | ||||||
|  | }) | ||||||
|  | const onRefresh = async () => { | ||||||
|  |   try { | ||||||
|  |     localState.value.refreshing = true | ||||||
|  |     localState.value.finished = false | ||||||
|  |     const { finished } = await getArtworkList(true) | ||||||
|  |     localState.value.finished = finished | ||||||
|  |   } finally { | ||||||
|  |     localState.value.refreshing = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const props = defineProps({ | ||||||
|  |   show: Boolean, | ||||||
|  |   title: { | ||||||
|  |     type: String, | ||||||
|  |     default: '' | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const scrollToCurrentItem = () => { | ||||||
|  |   if (!itemList.value?.length) return | ||||||
|  |   const currentIndex = itemList.value.findIndex( | ||||||
|  |       item => auctionData.value.artwork.index === item?.index | ||||||
|  |   ) | ||||||
|  |   if (currentIndex > -1) { | ||||||
|  |     const container = document.querySelector('.list-container') | ||||||
|  |     const targetElement = document.querySelectorAll('.item-wrapper')[currentIndex] | ||||||
|  |     if (targetElement && container) { | ||||||
|  |       const containerTop = container.getBoundingClientRect().top | ||||||
|  |       const elementTop = targetElement.getBoundingClientRect().top | ||||||
|  |       const scrollTop = elementTop - containerTop + container.scrollTop | ||||||
|  |       container.scrollTo({ | ||||||
|  |         top: scrollTop, | ||||||
|  |         behavior: 'smooth' | ||||||
|  |       }) | ||||||
|  |       toast.close() | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | const emit = defineEmits(['update:show']) | ||||||
|  | const showDetailInfo=ref(null) | ||||||
|  | const close = () => emit('update:show', false); | ||||||
|  | const openShow=(item)=>{ | ||||||
|  |   showDetailInfo.value=item | ||||||
|  |   showDetail.value=true | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | const loadMore = async () => { | ||||||
|  |   pageRef.value.page++ | ||||||
|  |   const { finished } = await getArtworkList() | ||||||
|  |   localState.value.finished = finished | ||||||
|  | } | ||||||
|  | watch(()=>{ | ||||||
|  |   return auctionData.value?.artwork?.index | ||||||
|  | },(newValue)=>{ | ||||||
|  |   }) | ||||||
|  | watch(()=>props.show,async (newValue)=>{ | ||||||
|  |   if (newValue){ | ||||||
|  |     if(auctionData.value?.artwork?.index>itemList.value?.length+1){ | ||||||
|  |       const toast = showLoadingToast({ | ||||||
|  |   message: '加载中...', | ||||||
|  |   forbidClick: true, | ||||||
|  | }); | ||||||
|  |       pageRef.value.pageSize=auctionData.value?.artwork?.index-itemList.value?.length | ||||||
|  |      await loadMore() | ||||||
|  |       | ||||||
|  |      pageRef.value.pageSize=5 | ||||||
|  |     } | ||||||
|  |  nextTick(()=>{ | ||||||
|  |    scrollToCurrentItem() | ||||||
|  |  }) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <x-popup :show="show" @update:show="close"> | ||||||
|  |       <template #title> | ||||||
|  |         <div class="text-#000 text-16px">{{ $t('home.tab1')}}</div> | ||||||
|  |         <div class="text-#939393 text-16px ml-14px">{{ $t('live_room.total') }}{{ pageRef.itemCount }}{{ $t('live_room.lots_num') }}</div> | ||||||
|  |       </template> | ||||||
|  |       <div> | ||||||
|  |         <van-pull-refresh | ||||||
|  |             v-model="localState.refreshing" | ||||||
|  |             :success-text="$t('home.refresh_show')" | ||||||
|  |             :success-duration="700" | ||||||
|  |             @refresh="onRefresh" | ||||||
|  |         > | ||||||
|  |           <template #success> | ||||||
|  |             <van-icon name="success" /> <span>{{ $t('home.refresh_show') }}</span> | ||||||
|  |           </template> | ||||||
|  |           <van-list | ||||||
|  |               v-model:loading="storeLoading" | ||||||
|  |               :finished="localState.finished" | ||||||
|  |               :finished-text="$t('home.finished_text')" | ||||||
|  |               @load="loadMore" | ||||||
|  | 
 | ||||||
|  |           > | ||||||
|  |             <div | ||||||
|  |                 v-for="(item,index) of itemList" | ||||||
|  |                 :key="item.uuid" | ||||||
|  |                 class="flex mb-21px item-wrapper" | ||||||
|  |                 @click="openShow(item)" | ||||||
|  |             > | ||||||
|  |               <div | ||||||
|  |                   class="mr-10px flex-shrink-0 rounded-4px overflow-hidden cursor-pointer relative" | ||||||
|  |               > | ||||||
|  |                 <xImage | ||||||
|  |                     :preview="false" | ||||||
|  |                     class="w-80px h-80px" | ||||||
|  |                     :src="item.artwork?.hdPic" | ||||||
|  |                     :alt="item?.artworkTitle" | ||||||
|  |                     loading="lazy" | ||||||
|  |                 /> | ||||||
|  |                 <div class="w-45px h-17px bg-#2B53AC text-12px line-height-none flex justify-center items-center absolute top-2px left-2px text-#fff">LOT{{item.index}}</div> | ||||||
|  |                 <div  v-show="auctionData?.artwork?.index===item?.index" class="w-80px h-20px bg-#B58047 flex line-height-none justify-center items-center text-#fff text-12px bottom-0 absolute blink">{{ $t('live_room.cast') }}</div> | ||||||
|  |               </div> | ||||||
|  |               <div> | ||||||
|  |                 <div class="ellipsis line-height-20px text-16px font-600 min-h-40px"> | ||||||
|  |                   {{ item.artworkTitle }} | ||||||
|  |                 </div> | ||||||
|  |                 <div class="text-14px text-#575757">{{ $t('home.start_price') }}:{{item?.startPriceCurrency}} {{item?.startPrice}}</div> | ||||||
|  |                 <div class="text-14px text-#B58047" v-if="item.soldPrice">{{ $t('home.close_price') }}:{{item.soldPrice}}</div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </van-list> | ||||||
|  |         </van-pull-refresh> | ||||||
|  |       </div> | ||||||
|  |     </x-popup> | ||||||
|  |     <DetailPopup v-model:show="showDetail" :detail-info="showDetailInfo"></DetailPopup> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | .ellipsis { | ||||||
|  |   display: -webkit-box; | ||||||
|  |   -webkit-box-orient: vertical; | ||||||
|  |   -webkit-line-clamp: 2; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | .blink { | ||||||
|  |   animation: fade 1s linear infinite; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes fade { | ||||||
|  |   0%, 100% { opacity: 1; } | ||||||
|  |   50% { opacity: 0.5; } | ||||||
|  | } | ||||||
|  | </style> | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user