fix: correct benefit tags and verification statistics
| | |
| | | <view v-if="initialLoading" class="list-state"><view class="loading-spinner"></view><text>正在加载观影服务</text></view> |
| | | <view v-else-if="initialError" class="list-state error-state"><text>观影服务加载失败</text><text class="retry-text" @tap="retryInitialLoad">重新加载</text></view> |
| | | <view v-else-if="hasLoaded && visibleServices.length == 0" class="list-state"><text>暂无相关观影服务</text></view> |
| | | <view v-else-if="hasLoaded"><view class="service-item" :class="item.available ? '' : 'is-unavailable'" v-for="item in visibleServices" :key="item.id" @tap="openService(item)"><image class="service-image" :src="item.image" mode="aspectFill" @error="replaceServiceImage(item)"></image><view class="service-info"><text class="service-name">{{item.name}}</text><text class="discount-tag">{{item.available ? item.discount : '已下架'}}</text><view class="address"><image src="/static/benefits-assets/map-pin.svg" mode="aspectFit"></image><text>{{item.address}}</text></view></view></view></view> |
| | | <view v-else-if="hasLoaded"><view class="service-item" :class="item.available ? '' : 'is-unavailable'" v-for="item in visibleServices" :key="item.id" @tap="openService(item)"><image class="service-image" :src="item.image" mode="aspectFill" @error="replaceServiceImage(item)"></image><view class="service-info"><text class="service-name">{{item.name}}</text><text v-if="!item.available || item.hasCoupon" class="discount-tag">{{item.available ? '券' : '已下架'}}</text><view class="address"><image src="/static/benefits-assets/map-pin.svg" mode="aspectFit"></image><text>{{item.address}}</text></view></view></view></view> |
| | | <view v-if="loadingMore" class="list-state compact"><view class="loading-spinner"></view><text>正在加载</text></view> |
| | | <view v-else-if="loadMoreError" class="list-state compact load-error" @tap="retryLoadMore"><text>加载失败,点击重试</text></view> |
| | | <view v-else-if="hasLoaded && !hasMore && visibleServices.length > 0" class="no-more"><text>已经到底了</text></view> |
| | |
| | | const next = append ? visibleServices.value.slice() : [] |
| | | for (let index = 0; index < records.length; index++) { |
| | | const item = records[index] |
| | | next.push({ id: '' + item.id, merchantType: item.merchantType != null ? item.merchantType as string : 'cinema', name: item.merchantName != null ? item.merchantName as string : '观影服务', discount: item.discountText != null ? item.discountText as string : '人才专享', address: item.address != null ? item.address as string : '', image: item.coverUrl != null && item.coverUrl != '' ? resolveApiUrl(item.coverUrl as string) : fallbackImage, available: item.available !== false }) |
| | | const hasCoupon = item.couponAvailable === true || Number(item.couponAvailable) == 1 || String(item.discountText).trim() == '券' |
| | | next.push({ id: '' + item.id, merchantType: item.merchantType != null ? item.merchantType as string : 'cinema', name: item.merchantName != null ? item.merchantName as string : '观影服务', discount: hasCoupon ? '券' : '', hasCoupon: hasCoupon, address: item.address != null ? item.address as string : '', image: item.coverUrl != null && item.coverUrl != '' ? resolveApiUrl(item.coverUrl as string) : fallbackImage, available: item.available !== false }) |
| | | } |
| | | visibleServices.value = next |
| | | currentPage.value++ |
| | |
| | | export const getStayTopicMerchants = (type: string, page: number, size: number, talentId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => { |
| | | const data: any = { type: type, page: page, size: size } |
| | | if (talentId != '') data.talentId = Number(talentId) |
| | | return request<any>({ path: getApiEndpoint('appStayTopicMerchants'), method: 'GET', skipAuth: true, data: data }, onSuccess, onError) |
| | | return request<any>({ path: getApiEndpoint('appStayTopicMerchants'), method: 'GET', data: data }, onSuccess, onError) |
| | | } |
| | | export const getEntertainmentTopic = (onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appEntertainmentTopic'), method: 'GET', skipAuth: true }, onSuccess, onError) |
| | | export const getEntertainmentTopicMerchants = (page: number, size: number, onSuccess: (data: any) => void, onError: (error: HttpError) => void): (() => void) => request<any>({ path: getApiEndpoint('appEntertainmentTopicMerchants'), method: 'GET', skipAuth: true, data: { page: page, size: size } }, onSuccess, onError) |
| | |
| | | @RequestParam(defaultValue = "hotel") String type, |
| | | @RequestParam(defaultValue = "1") int page, |
| | | @RequestParam(defaultValue = "4") int size, |
| | | @RequestParam(required = false) Long talentId |
| | | @RequestParam(required = false) Long talentId, |
| | | @RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authorization |
| | | ) { |
| | | return ApiResponse.success(portalService.stayMerchants(type, page, size, talentId)); |
| | | return ApiResponse.success(portalService.stayMerchants(type, page, size, sessionTalentId(authorization, talentId))); |
| | | } |
| | | |
| | | @GetMapping("/topics/entertainment") |
| | |
| | | PageResult<Map<String, Object>> result = page(""" |
| | | select id, merchant_name, merchant_type_code as merchant_type, contact_name, contact_mobile, logo_url, cover_url, address, |
| | | service_label, status, sort_no, longitude, latitude, business_status, |
| | | (exists(select 1 from merchant_coupon c |
| | | where c.merchant_id = merchant.id and c.deleted = 0 and c.status = 1 |
| | | and (c.valid_start is null or c.valid_start <= current_date) |
| | | and (c.valid_end is null or c.valid_end >= current_date)) |
| | | or exists(select 1 from ticket_package p |
| | | where p.deleted = 0 and p.status = 1 |
| | | and (p.valid_start is null or p.valid_start <= current_date) |
| | | and (p.valid_end is null or p.valid_end >= current_date) |
| | | and (p.merchant_id = merchant.id or exists ( |
| | | select 1 from ticket_package_merchant pm |
| | | where pm.package_id = p.id and pm.merchant_id = merchant.id and pm.deleted = 0 |
| | | )))) as coupon_available, |
| | | (select min(p.sale_price) from merchant_product p where p.merchant_id = merchant.id and p.deleted = 0 and p.status = 1 and p.audit_status = 2) as sale_price, |
| | | (select min(p.original_price) from merchant_product p where p.merchant_id = merchant.id and p.deleted = 0 and p.status = 1 and p.audit_status = 2) as original_price |
| | | from merchant |
| | |
| | | "select count(*) from merchant" + merchantWhere, page, size); |
| | | List<Map<String, Object>> records = result.records().stream().map(row -> { |
| | | Map<String, Object> item = enrichMerchantSearchRow(row); |
| | | item.put("discountText", textOrDefault(item.get("serviceLabel"), textOrDefault(item.get("discountText"), "人才专享"))); |
| | | boolean couponAvailable = booleanValue(item.get("couponAvailable")); |
| | | item.put("couponAvailable", couponAvailable); |
| | | item.put("discountText", couponAvailable ? "券" : ""); |
| | | return item; |
| | | }).toList(); |
| | | return new PageResult<>(records, result.page(), result.size(), result.total()); |
| | |
| | | && booleanValue(configuredRight.get("storeConsume")) |
| | | && booleanValue(configuredRight.get("consumeEnabled"))); |
| | | if (configuredRight != null) { |
| | | item.put("discountText", textOrDefault(configuredRight.get("tag"), textOrDefault(item.get("serviceLabel"), ""))); |
| | | item.put("discountText", merchantRightDiscountText(configuredRight)); |
| | | item.put("rightsAvailable", true); |
| | | } else if (levelRight != null || !rights.isEmpty()) { |
| | | item.put("discountText", levelRight == null ? "" : textOrDefault(levelRight.get("tag"), "")); |
| | | item.put("discountText", levelRight == null ? "" : merchantRightDiscountText(levelRight)); |
| | | item.put("rightsAvailable", false); |
| | | item.put("available", false); |
| | | item.put("unavailableReason", levelRight == null ? "当前人才卡暂未配置该权益" : "当前人才卡暂未开通该权益"); |
| | |
| | | return new PageResult<>(records, result.page(), result.size(), result.total()); |
| | | } |
| | | |
| | | private String merchantRightDiscountText(Map<String, Object> right) { |
| | | if (!booleanValue(right.get("storeConsume")) || !booleanValue(right.get("consumeEnabled"))) return ""; |
| | | String discount = textOrDefault(right.get("discount"), "").trim(); |
| | | if (discount.isBlank()) return ""; |
| | | try { |
| | | BigDecimal value = new BigDecimal(discount).stripTrailingZeros(); |
| | | if (value.compareTo(BigDecimal.ZERO) <= 0 || value.compareTo(BigDecimal.TEN) > 0) return ""; |
| | | return value.toPlainString() + "折"; |
| | | } catch (NumberFormatException ignored) { |
| | | return ""; |
| | | } |
| | | } |
| | | |
| | | @Transactional(readOnly = true) |
| | | public Map<String, Object> premiumTopic() { |
| | | Map<String, Object> topic = one(""" |
| | |
| | | when coalesce(o.subsidy_amount, 0) > 0 |
| | | and (o.product_id is null or coalesce(p.is_government_subsidy, 0) = 1) |
| | | then o.subsidy_amount else 0 end), 0) as subsidyAmountCents, |
| | | (select count(*) from verify_record v |
| | | where v.status = 1 |
| | | and v.verify_time >= date_format(current_date, '%Y-%m-01') |
| | | and v.verify_time < date_add(last_day(current_date), interval 1 day)) as monthlyVerificationCount, |
| | | (select count(*) from benefit_order verified_order |
| | | where verified_order.deleted = 0 |
| | | and verified_order.order_status = 1 |
| | | and verified_order.verify_status = 1 |
| | | and coalesce( |
| | | (select max(v.verify_time) from verify_record v |
| | | where v.order_id = verified_order.id and v.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = verified_order.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | verified_order.updated_at |
| | | ) >= date_format(current_date, '%Y-%m-01') |
| | | and coalesce( |
| | | (select max(v.verify_time) from verify_record v |
| | | where v.order_id = verified_order.id and v.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = verified_order.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | verified_order.updated_at |
| | | ) < date_add(last_day(current_date), interval 1 day)) as monthlyVerificationCount, |
| | | (select count(*) from talent_user u where u.deleted = 0) as talentCount, |
| | | (select count(*) from benefit_order po where po.deleted = 0 and po.order_status = 0) as pendingOrderCount, |
| | | (select count(*) from merchant_product pp where pp.deleted = 0 and pp.audit_status = 1) as pendingProductCount, |
| | |
| | | coalesce((select count(*) from talent_user u |
| | | where u.deleted = 0 |
| | | and date(u.created_at) = date_sub(current_date, interval 1 day)), 0) as talentCompare, |
| | | (coalesce((select count(*) from verify_record current_month_verify |
| | | where current_month_verify.status = 1 |
| | | and current_month_verify.verify_time >= date_format(current_date, '%Y-%m-01') |
| | | and current_month_verify.verify_time < date_add(last_day(current_date), interval 1 day)), 0) |
| | | - coalesce((select count(*) from verify_record previous_month_verify |
| | | where previous_month_verify.status = 1 |
| | | and previous_month_verify.verify_time >= date_sub(date_format(current_date, '%Y-%m-01'), interval 1 month) |
| | | and previous_month_verify.verify_time < date_format(current_date, '%Y-%m-01')), 0)) as monthlyVerificationCompare, |
| | | (coalesce((select count(*) from benefit_order current_month_order |
| | | where current_month_order.deleted = 0 |
| | | and current_month_order.order_status = 1 |
| | | and current_month_order.verify_status = 1 |
| | | and coalesce( |
| | | (select max(v.verify_time) from verify_record v |
| | | where v.order_id = current_month_order.id and v.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = current_month_order.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | current_month_order.updated_at |
| | | ) >= date_format(current_date, '%Y-%m-01') |
| | | and coalesce( |
| | | (select max(v.verify_time) from verify_record v |
| | | where v.order_id = current_month_order.id and v.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = current_month_order.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | current_month_order.updated_at |
| | | ) < date_add(last_day(current_date), interval 1 day)), 0) |
| | | - coalesce((select count(*) from benefit_order previous_month_order |
| | | where previous_month_order.deleted = 0 |
| | | and previous_month_order.order_status = 1 |
| | | and previous_month_order.verify_status = 1 |
| | | and coalesce( |
| | | (select max(v.verify_time) from verify_record v |
| | | where v.order_id = previous_month_order.id and v.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = previous_month_order.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | previous_month_order.updated_at |
| | | ) >= date_sub(date_format(current_date, '%Y-%m-01'), interval 1 month) |
| | | and coalesce( |
| | | (select max(v.verify_time) from verify_record v |
| | | where v.order_id = previous_month_order.id and v.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = previous_month_order.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | previous_month_order.updated_at |
| | | ) < date_format(current_date, '%Y-%m-01')), 0)) as monthlyVerificationCompare, |
| | | coalesce(sum(case |
| | | when coalesce(o.subsidy_amount, 0) > 0 |
| | | and (o.product_id is null or coalesce(p.is_government_subsidy, 0) = 1) |
| | |
| | | where u.deleted = 0 |
| | | and u.created_at < date_add(days.bucket_day, interval 1 day)) as talent, |
| | | (select count(*) |
| | | from verify_record v |
| | | where v.status = 1 |
| | | and v.verify_time >= days.bucket_day |
| | | and v.verify_time < date_add(days.bucket_day, interval 1 day)) as verification, |
| | | from benefit_order verified_order |
| | | where verified_order.deleted = 0 |
| | | and verified_order.order_status = 1 |
| | | and verified_order.verify_status = 1 |
| | | and coalesce( |
| | | (select max(v.verify_time) from verify_record v |
| | | where v.order_id = verified_order.id and v.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = verified_order.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | verified_order.updated_at |
| | | ) >= days.bucket_day |
| | | and coalesce( |
| | | (select max(v.verify_time) from verify_record v |
| | | where v.order_id = verified_order.id and v.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = verified_order.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | verified_order.updated_at |
| | | ) < date_add(days.bucket_day, interval 1 day)) as verification, |
| | | round(coalesce((select sum(case |
| | | when coalesce(o.subsidy_amount, 0) > 0 |
| | | and (o.product_id is null or coalesce(p.is_government_subsidy, 0) = 1) |
| | |
| | | @Select(""" |
| | | select buckets.bucket_time as time, |
| | | coalesce(count(v.id), 0) as `order`, |
| | | round(coalesce(sum(v.verify_amount), 0) / 100, 2) as amount |
| | | round(coalesce(sum(v.pay_amount), 0) / 100, 2) as amount |
| | | from ( |
| | | select 0 bucket_hour, '0:00' bucket_time union all select 2, '2:00' |
| | | union all select 4, '4:00' union all select 6, '6:00' |
| | |
| | | union all select 16, '16:00' union all select 18, '18:00' |
| | | union all select 20, '20:00' union all select 22, '22:00' |
| | | ) buckets |
| | | left join verify_record v on v.status = 1 |
| | | and v.verify_time >= current_date |
| | | and v.verify_time < date_add(current_date, interval 1 day) |
| | | and floor(hour(v.verify_time) / 2) * 2 = buckets.bucket_hour |
| | | left join ( |
| | | select o.id, o.pay_amount, |
| | | coalesce( |
| | | (select max(vr.verify_time) from verify_record vr where vr.order_id = o.id and vr.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = o.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | o.updated_at |
| | | ) as effective_time |
| | | from benefit_order o |
| | | where o.deleted = 0 and o.order_status = 1 and o.verify_status = 1 |
| | | ) v on v.effective_time >= current_date |
| | | and v.effective_time < date_add(current_date, interval 1 day) |
| | | and floor(hour(v.effective_time) / 2) * 2 = buckets.bucket_hour |
| | | group by buckets.bucket_hour, buckets.bucket_time |
| | | order by buckets.bucket_hour |
| | | """) |
| | |
| | | @Select(""" |
| | | select date_format(days.bucket_day, '%c/%e') as time, |
| | | coalesce(count(v.id), 0) as `order`, |
| | | round(coalesce(sum(v.verify_amount), 0) / 100, 2) as amount |
| | | round(coalesce(sum(v.pay_amount), 0) / 100, 2) as amount |
| | | from ( |
| | | select date_sub(current_date, interval 6 day) as bucket_day union all |
| | | select date_sub(current_date, interval 5 day) union all |
| | |
| | | select date_sub(current_date, interval 1 day) union all |
| | | select current_date |
| | | ) days |
| | | left join verify_record v on v.status = 1 |
| | | and v.verify_time >= days.bucket_day |
| | | and v.verify_time < date_add(days.bucket_day, interval 1 day) |
| | | left join ( |
| | | select o.id, o.pay_amount, |
| | | coalesce( |
| | | (select max(vr.verify_time) from verify_record vr where vr.order_id = o.id and vr.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = o.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | o.updated_at |
| | | ) as effective_time |
| | | from benefit_order o |
| | | where o.deleted = 0 and o.order_status = 1 and o.verify_status = 1 |
| | | ) v on v.effective_time >= days.bucket_day |
| | | and v.effective_time < date_add(days.bucket_day, interval 1 day) |
| | | group by days.bucket_day |
| | | order by days.bucket_day |
| | | """) |
| | |
| | | @Select(""" |
| | | select concat(weeks.week_start, '~', weeks.week_end) as time, |
| | | coalesce(count(v.id), 0) as `order`, |
| | | round(coalesce(sum(v.verify_amount), 0) / 100, 2) as amount |
| | | round(coalesce(sum(v.pay_amount), 0) / 100, 2) as amount |
| | | from ( |
| | | select 0 bucket_index, |
| | | date_format(date_add(date_sub(current_date, interval dayofmonth(current_date) - 1 day), interval 0 day), '%c/%e') as week_start, |
| | |
| | | date_add(date_sub(current_date, interval dayofmonth(current_date) - 1 day), interval 28 day), |
| | | last_day(current_date) |
| | | ) weeks |
| | | left join verify_record v on v.status = 1 |
| | | and v.verify_time >= weeks.start_date |
| | | and v.verify_time < date_add(weeks.end_date, interval 1 day) |
| | | left join ( |
| | | select o.id, o.pay_amount, |
| | | coalesce( |
| | | (select max(vr.verify_time) from verify_record vr where vr.order_id = o.id and vr.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = o.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | o.updated_at |
| | | ) as effective_time |
| | | from benefit_order o |
| | | where o.deleted = 0 and o.order_status = 1 and o.verify_status = 1 |
| | | ) v on v.effective_time >= weeks.start_date |
| | | and v.effective_time < date_add(weeks.end_date, interval 1 day) |
| | | where weeks.start_date <= last_day(current_date) |
| | | group by weeks.bucket_index, weeks.week_start, weeks.week_end, weeks.start_date |
| | | order by weeks.bucket_index |
| | |
| | | @Select(""" |
| | | select concat(months.bucket_month, '月') as time, |
| | | coalesce(count(v.id), 0) as `order`, |
| | | round(coalesce(sum(v.verify_amount), 0) / 100, 2) as amount |
| | | round(coalesce(sum(v.pay_amount), 0) / 100, 2) as amount |
| | | from ( |
| | | select 1 bucket_month union all select 2 union all select 3 union all select 4 |
| | | union all select 5 union all select 6 union all select 7 union all select 8 |
| | | union all select 9 union all select 10 union all select 11 union all select 12 |
| | | ) months |
| | | left join verify_record v on v.status = 1 |
| | | and year(v.verify_time) = year(current_date) |
| | | and month(v.verify_time) = months.bucket_month |
| | | left join ( |
| | | select o.id, o.pay_amount, |
| | | coalesce( |
| | | (select max(vr.verify_time) from verify_record vr where vr.order_id = o.id and vr.status = 1), |
| | | (select max(pt.paid_at) from payment_transaction pt |
| | | where pt.order_no = o.order_no and pt.status = 'SUCCEEDED' and pt.paid_at is not null), |
| | | o.updated_at |
| | | ) as effective_time |
| | | from benefit_order o |
| | | where o.deleted = 0 and o.order_status = 1 and o.verify_status = 1 |
| | | ) v on year(v.effective_time) = year(current_date) |
| | | and month(v.effective_time) = months.bucket_month |
| | | group by months.bucket_month |
| | | order by months.bucket_month |
| | | """) |
| New file |
| | |
| | | package com.talentcard.server.business.portal; |
| | | |
| | | import static org.mockito.Mockito.verify; |
| | | import static org.mockito.Mockito.when; |
| | | |
| | | import java.util.List; |
| | | |
| | | import com.talentcard.server.business.PageResult; |
| | | import com.talentcard.server.business.auth.TalentAuthService; |
| | | import com.talentcard.server.business.auth.TalentSessionPrincipal; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.junit.jupiter.api.extension.ExtendWith; |
| | | import org.mockito.InjectMocks; |
| | | import org.mockito.Mock; |
| | | import org.mockito.junit.jupiter.MockitoExtension; |
| | | |
| | | @ExtendWith(MockitoExtension.class) |
| | | class PortalControllerTests { |
| | | |
| | | @Mock |
| | | private PortalService portalService; |
| | | |
| | | @Mock |
| | | private TalentAuthService talentAuthService; |
| | | |
| | | @InjectMocks |
| | | private PortalController controller; |
| | | |
| | | @Test |
| | | void stayMerchantsUsesTalentIdFromAuthenticatedSession() { |
| | | when(talentAuthService.authenticate("Bearer session-token")) |
| | | .thenReturn(new TalentSessionPrincipal(42L)); |
| | | when(portalService.stayMerchants("hotel", 1, 4, 42L)) |
| | | .thenReturn(new PageResult<>(List.of(), 1, 4, 0)); |
| | | |
| | | controller.stayMerchants("hotel", 1, 4, 7L, "Bearer session-token"); |
| | | |
| | | verify(portalService).stayMerchants("hotel", 1, 4, 42L); |
| | | } |
| | | |
| | | @Test |
| | | void stayMerchantsKeepsQueryTalentIdForUnauthenticatedRequests() { |
| | | when(portalService.stayMerchants("hotel", 1, 4, 7L)) |
| | | .thenReturn(new PageResult<>(List.of(), 1, 4, 0)); |
| | | |
| | | controller.stayMerchants("hotel", 1, 4, 7L, null); |
| | | |
| | | verify(portalService).stayMerchants("hotel", 1, 4, 7L); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.talentcard.server.business.portal; |
| | | |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | | import static org.mockito.ArgumentMatchers.any; |
| | | import static org.mockito.ArgumentMatchers.anyString; |
| | | import static org.mockito.ArgumentMatchers.eq; |
| | | import static org.mockito.Mockito.when; |
| | | |
| | | import java.lang.reflect.Method; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import org.junit.jupiter.api.Test; |
| | | import org.junit.jupiter.api.extension.ExtendWith; |
| | | import org.mockito.InjectMocks; |
| | | import org.mockito.Mock; |
| | | import org.mockito.junit.jupiter.MockitoExtension; |
| | | import org.springframework.jdbc.core.JdbcTemplate; |
| | | |
| | | @ExtendWith(MockitoExtension.class) |
| | | class PortalServiceTests { |
| | | |
| | | @Mock |
| | | private JdbcTemplate jdbc; |
| | | |
| | | @InjectMocks |
| | | private PortalService service; |
| | | |
| | | @Test |
| | | void cinemaMerchantOnlyShowsCouponTagWhenAnActiveCouponExists() { |
| | | when(jdbc.queryForList(anyString(), any(Object[].class))).thenReturn(List.of( |
| | | Map.of("id", 1L, "merchant_name", "有券影院", "merchant_type", "cinema", "status", 1, "coupon_available", 1), |
| | | Map.of("id", 2L, "merchant_name", "无券影院", "merchant_type", "cinema", "status", 1, "coupon_available", 0))); |
| | | when(jdbc.queryForObject(anyString(), eq(Long.class), any(Object[].class))).thenReturn(2L); |
| | | |
| | | var result = service.entertainmentMerchants(1, 4); |
| | | |
| | | assertThat(result.records().get(0)) |
| | | .containsEntry("couponAvailable", true) |
| | | .containsEntry("discountText", "券"); |
| | | assertThat(result.records().get(1)) |
| | | .containsEntry("couponAvailable", false) |
| | | .containsEntry("discountText", ""); |
| | | } |
| | | |
| | | @Test |
| | | void shoppingMerchantUsesConfiguredStoreDiscountInsteadOfRightsTag() throws Exception { |
| | | Method method = PortalService.class.getDeclaredMethod("merchantRightDiscountText", Map.class); |
| | | method.setAccessible(true); |
| | | |
| | | String discount = (String) method.invoke(service, Map.of( |
| | | "enabled", true, |
| | | "tag", "卓越人才到店消费可用", |
| | | "storeConsume", true, |
| | | "consumeEnabled", true, |
| | | "discount", "8.50")); |
| | | |
| | | assertThat(discount).isEqualTo("8.5折"); |
| | | } |
| | | } |