fix(talent): personalize food benefit tags
| | |
| | | <image class="merchant-image" :src="item.image" mode="aspectFill" @error="replaceMerchantImage(item)"></image> |
| | | <view class="merchant-info"> |
| | | <text class="merchant-name">{{item.name}}</text> |
| | | <view class="tag-row"><text class="coupon-tag">券</text><text class="discount-tag">{{item.available ? item.discount : '已下架'}}</text></view> |
| | | <view v-if="!item.available || item.hasCoupon || item.discount != ''" class="tag-row"><text v-if="item.hasCoupon" class="coupon-tag">券</text><text v-if="!item.available || item.discount != ''" class="discount-tag">{{item.available ? item.discount : '已下架'}}</text></view> |
| | | <view class="address-row"><image src="/static/benefits-assets/map-pin.svg"></image><text>{{item.address}}</text></view> |
| | | </view> |
| | | </view> |
| | |
| | | import { isApiConfigured } from '../../config/api.uts' |
| | | import { getFoodTopic, getFoodTopicMerchants } from '../../services/portal.uts' |
| | | import { resolveApiUrl } from '../../services/http.uts' |
| | | import { getSession } from '../../services/session.uts' |
| | | import { safeBack } from '../../utils/navigation.uts' |
| | | |
| | | const navTop = ref(28) |
| | |
| | | const failLoadMoreOnce = ref(false) |
| | | const currentPage = ref(0) |
| | | const listRequestVersion = ref(0) |
| | | const talentId = ref('') |
| | | |
| | | onLoad((options: any) => { |
| | | // #ifdef MP-WEIXIN |
| | |
| | | failInitialOnce.value = previewState == 'initialError' |
| | | failLoadMoreOnce.value = previewState == 'loadMoreError' |
| | | } |
| | | const session = getSession() |
| | | if (session != null && session.talentId != null) talentId.value = session.talentId as string |
| | | loadFoodTopic() |
| | | loadInitialMerchants() |
| | | }) |
| | |
| | | loadMoreError.value = true |
| | | return |
| | | } |
| | | getFoodTopicMerchants(currentPage.value + 1, 4, (data: any) => { |
| | | getFoodTopicMerchants(currentPage.value + 1, 4, talentId.value, (data: any) => { |
| | | if (requestVersion != listRequestVersion.value) return |
| | | const records: any[] = data != null && data.records instanceof Array ? data.records as any[] : [] |
| | | const next = append ? visibleMerchants.value.slice() : [] |
| | |
| | | id: '' + item.id, |
| | | name: item.merchantName != null ? item.merchantName as string : '餐饮商户', |
| | | merchantType: item.merchantType != null ? item.merchantType as string : 'food', |
| | | discount: item.discountText != null ? item.discountText as string : '人才专享', |
| | | discount: item.discountText != null ? item.discountText as string : '', |
| | | hasCoupon: item.couponAvailable === true || Number(item.couponAvailable) == 1, |
| | | address: item.address != null ? item.address as string : '', |
| | | image: item.coverUrl != null && item.coverUrl != '' ? resolveApiUrl(item.coverUrl as string) : fallbackFoodImage, |
| | | available: item.available !== false |
| | |
| | | return request<any>({ path: getApiEndpoint('appFoodTopic'), method: 'GET', skipAuth: true }, onSuccess, onError) |
| | | } |
| | | |
| | | export const getFoodTopicMerchants = (page: number, size: number, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => { |
| | | return request<any>({ path: getApiEndpoint('appFoodTopicMerchants'), method: 'GET', skipAuth: true, data: { page: page, size: size } }, onSuccess, onError) |
| | | export const getFoodTopicMerchants = (page: number, size: number, talentId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => { |
| | | const data: any = { page: page, size: size } |
| | | if (talentId != '') data.talentId = Number(talentId) |
| | | return request<any>({ path: getApiEndpoint('appFoodTopicMerchants'), method: 'GET', skipAuth: true, data: data }, onSuccess, onError) |
| | | } |
| | | |
| | | export const getTravelTopic = (onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appTravelTopic'), method: 'GET', skipAuth: true }, onSuccess, onError) |
| | |
| | | @GetMapping("/topics/food/merchants") |
| | | public ApiResponse<PageResult<Map<String, Object>>> foodMerchants( |
| | | @RequestParam(defaultValue = "1") int page, |
| | | @RequestParam(defaultValue = "4") int size |
| | | @RequestParam(defaultValue = "4") int size, |
| | | @RequestParam(required = false) Long talentId |
| | | ) { |
| | | return ApiResponse.success(portalService.foodMerchants(page, size)); |
| | | return ApiResponse.success(portalService.foodMerchants(page, size, talentId)); |
| | | } |
| | | |
| | | @GetMapping("/topics/travel") |
| | |
| | | } |
| | | |
| | | @Transactional(readOnly = true) |
| | | public PageResult<Map<String, Object>> foodMerchants(int page, int size) { |
| | | public PageResult<Map<String, Object>> foodMerchants(int page, int size, Long talentId) { |
| | | String merchantWhere = " where deleted = 0 and merchant_type in ('food', '餐饮服务')"; |
| | | PageResult<Map<String, Object>> result = page(""" |
| | | select id, merchant_name, merchant_type, contact_name, contact_mobile, logo_url, cover_url, address, |
| | |
| | | from merchant |
| | | """ + merchantWhere + " order by sort_no asc, id asc", |
| | | "select count(*) from merchant" + merchantWhere, page, size); |
| | | List<Map<String, Object>> records = result.records().stream().map(this::enrichMerchantSearchRow).toList(); |
| | | List<Map<String, Object>> records = result.records().stream().map(row -> { |
| | | Map<String, Object> item = enrichMerchantSearchRow(row); |
| | | Long merchantId = item.get("id") instanceof Number id ? id.longValue() : null; |
| | | item.put("couponAvailable", merchantId != null && hasActiveMerchantCoupon(merchantId)); |
| | | item.put("discountText", merchantId == null ? "" : merchantLowestTalentDiscount(merchantId, talentId)); |
| | | return item; |
| | | }).toList(); |
| | | return new PageResult<>(records, result.page(), result.size(), result.total()); |
| | | } |
| | | |