feat:权益卡片的调整
This commit is contained in:
@@ -3,13 +3,12 @@
|
||||
* 权益卡(全站唯一组件 · 4 处复用)
|
||||
* 使用位置:权益中心 / 我的权益 / 详情页「到店权益」
|
||||
* 四行固定顺序:类型 / 价格 / 规格·适用 / 有效期·名额
|
||||
* 价格两形态互斥:金额型 = 优惠价大字 + 划线原价 + 右端折扣标;
|
||||
* 折扣型(price.rate)= 「门市价」小字 + 折扣大字,不再出划线原价与折扣标。
|
||||
* 「进入商家」入口在权益中心与我的权益都出现(详情页本就在该商家内,不加)。
|
||||
* 价格两形态互斥:金额型 = 优惠价大字 + 划线原价 + 右端折扣标;折扣型(price.rate)= 折扣大字。
|
||||
* ①行=类型短名(2 字,`BENEFIT_TYPE_SHORT`)+ 右端商家名胶囊(`merchant_name`,超 8 字截断),详情页不加胶囊。
|
||||
*/
|
||||
import { computed } from "vue";
|
||||
import { BENEFIT_STATUS, BENEFIT_TYPE_ICON, BENEFIT_TYPE_LABEL } from "@/constant";
|
||||
import { basisText, discountLabel, dotDate, rateText, yuanText } from "@/utils";
|
||||
import { BENEFIT_STATUS, BENEFIT_TYPE_ICON, BENEFIT_TYPE_SHORT } from "@/constant";
|
||||
import { discountLabel, dotDate, rateText, yuanText } from "@/utils";
|
||||
import { goDetail } from "@/utils/nav";
|
||||
|
||||
const props = defineProps({
|
||||
@@ -30,14 +29,13 @@ const isClaimed = computed(() => status.value === BENEFIT_STATUS.CLAIMED);
|
||||
|
||||
/** 权益类型键:详情页走接口的 section_key,权益中心仍是本地 type,两者取其一 */
|
||||
const typeKey = computed(() => b.value.section_key || b.value.type || "");
|
||||
const typeLabel = computed(() => BENEFIT_TYPE_LABEL[typeKey.value] || "权益");
|
||||
const typeLabel = computed(() => BENEFIT_TYPE_SHORT[typeKey.value] || "权益");
|
||||
const typeIcon = computed(() => BENEFIT_TYPE_ICON[typeKey.value] || "gift");
|
||||
|
||||
const deal = computed(() => yuanText(b.value.price?.deal));
|
||||
const original = computed(() => yuanText(b.value.price?.original));
|
||||
const pct = computed(() => discountLabel(b.value.price?.deal, b.value.price?.original));
|
||||
const rate = computed(() => rateText(b.value.price));
|
||||
const basis = computed(() => basisText(b.value.price));
|
||||
const isRate = computed(() => !!rate.value);
|
||||
const spec = computed(() => b.value.price?.spec || "");
|
||||
const hasPrice = computed(() => isRate.value || !!deal.value);
|
||||
@@ -109,6 +107,13 @@ const goStateCls = computed(() =>
|
||||
);
|
||||
const goIconTone = computed(() => (isOff.value ? "ink3" : "accentDeep"));
|
||||
|
||||
/** 「进入商家」胶囊文案:取商家上架名称,超 8 字截断加省略号 */
|
||||
const goLabel = computed(() => {
|
||||
const name = String(b.value.merchant_name || "").trim();
|
||||
if (!name) return "进入商家";
|
||||
return name.length > 8 ? `${name.slice(0, 8)}…` : name;
|
||||
});
|
||||
|
||||
/** 跳该权益所属商家详情 */
|
||||
const onGoMerchant = () => {
|
||||
if (b.value.merchant_id) goDetail(b.value.merchant_id);
|
||||
@@ -126,15 +131,15 @@ const onTap = () => {
|
||||
<!-- 左:信息区(四行固定顺序) -->
|
||||
<view class="flex-1 min-w-0 rounded-l-card px-[14px] pt-[13px] pb-3 flex flex-col" :class="sideStateCls">
|
||||
<!-- ① 类型(权益中心 / 我的权益在行右端带「进入商家」入口) -->
|
||||
<view class="flex items-center gap-[6px] text-[13px] font-semibold whitespace-nowrap" :class="kindStateCls">
|
||||
<view class="flex items-center gap-2 text-[13px] font-semibold whitespace-nowrap" :class="kindStateCls">
|
||||
<view class="w-[21px] h-[21px] rounded-full shrink-0 flex items-center justify-center" :class="kindIconCls">
|
||||
<AppIcon :name="typeIcon" tone="white" :size="12.5" />
|
||||
</view>
|
||||
<text>{{ typeLabel }}</text>
|
||||
<view class="min-w-0 flex-1 line-clamp-1">{{ typeLabel }}</view>
|
||||
<view v-if="mode !== 'detail'"
|
||||
class="ml-auto shrink-0 h-5 px-2 rounded-full flex items-center gap-[2px] text-hint font-semibold border-[0.5px]"
|
||||
class="ml-auto shrink-0 -mr-0.5 h-5 pl-2 pr-1.5 rounded-full flex items-center gap-[2px] text-hint font-semibold border-[0.5px]"
|
||||
:class="goStateCls" @click.stop="onGoMerchant">
|
||||
<text>进入商家</text>
|
||||
<view class="min-w-0 line-clamp-1">{{ goLabel }}</view>
|
||||
<AppIcon name="chev" :tone="goIconTone" :size="11" />
|
||||
</view>
|
||||
</view>
|
||||
@@ -142,7 +147,6 @@ const onTap = () => {
|
||||
<!-- ② 价格:金额型 = 优惠价 + 划线原价 + 折扣标;折扣型 = 门市价 + 折扣大字 -->
|
||||
<view v-if="hasPrice" class="flex items-baseline gap-[6px] mt-2 leading-none whitespace-nowrap">
|
||||
<template v-if="isRate">
|
||||
<text v-if="basis" class="text-[11.5px] font-medium" :class="wasCls">{{ basis }}</text>
|
||||
<text class="text-display font-extrabold tracking-[-1px]" :class="priceNumCls">{{ rate }}</text>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
import { computed } from "vue";
|
||||
import { BENEFIT_TYPE_LABEL } from "@/constant";
|
||||
import { basisText, dateRangeText, dotDateTime, rateText, yuanText } from "@/utils";
|
||||
import { dateRangeText, dotDateTime, rateText, yuanText } from "@/utils";
|
||||
|
||||
const props = defineProps({
|
||||
visible: { type: Boolean, default: false },
|
||||
@@ -30,7 +30,7 @@ const typeLabel = computed(() => BENEFIT_TYPE_LABEL[typeKey.value] || "权益");
|
||||
|
||||
const priceLine = computed(() => {
|
||||
const rate = rateText(b.value.price);
|
||||
if (rate) return `${basisText(b.value.price)}${rate}`;
|
||||
if (rate) return rate;
|
||||
const deal = yuanText(b.value.price?.deal);
|
||||
const original = yuanText(b.value.price?.original);
|
||||
if (!deal) return b.value.scope_desc || "";
|
||||
|
||||
@@ -47,6 +47,15 @@ export const BENEFIT_TYPE_LABEL = {
|
||||
general: "通用权益",
|
||||
};
|
||||
|
||||
/** 权益类型 → 卡片类型行短名(权益卡①行空间有限,2 字上限;图标已承担类型辨识) */
|
||||
export const BENEFIT_TYPE_SHORT = {
|
||||
scenic: "景区",
|
||||
stay: "住宿",
|
||||
food: "餐饮",
|
||||
specialty: "特产",
|
||||
general: "通用",
|
||||
};
|
||||
|
||||
/** 权益类型 → 卡片类型行图标 */
|
||||
export const BENEFIT_TYPE_ICON = {
|
||||
scenic: "peak",
|
||||
|
||||
Reference in New Issue
Block a user