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