automated_uniapp/uni_modules/cool-fixtures/components/fix-coupon/fix-coupon.vue
2025-01-09 16:40:44 +08:00

222 lines
4.0 KiB
Vue

<template>
<fix-base-style
:styleSpacing="styleSpacing"
:styleColor="styleColor"
:position="position"
:index="index"
>
<div class="fix-coupon" v-if="item.id" :style="couponStyle">
<div class="coupon-activity" @tap="toGet">
<div class="a">
<div class="text">
<span class="name">{{ item?.title }}</span>
<span class="desc">{{ item?.description }}</span>
</div>
<span class="tag" v-if="item">点击领券</span>
</div>
<div class="b">
<template v-if="item">
<span class="amount">{{ item?.amount || 0 }}</span>
<span class="doc">
{{ doc }}
</span>
</template>
</div>
<div class="c"></div>
</div>
</div>
</fix-base-style>
</template>
<script lang="ts" name="fix-coupon" setup>
import { computed, type PropType } from "vue";
import { baseProps } from "../../hooks";
import { useCool } from "/@/cool";
import { useUi } from "/$/cool-ui";
const { service } = useCool();
const ui = useUi();
const props = defineProps({
item: {
type: Object as PropType<Eps.MarketCouponInfoEntity>,
default: () => {
return {
id: 0,
title: "",
description: "",
amount: 0,
type: 0,
condition: "",
};
},
},
color: {
type: String,
default: "#2b2e3d",
},
index: {
type: Number,
default: 0,
},
...baseProps,
});
// 领取
function toGet() {
service.market.coupon.user
.receive({
couponId: props.item?.id,
})
.then(() => {
ui.showToast("领取成功");
})
.catch((err) => {
ui.showToast(err.message);
});
}
/**
* 将十六进制颜色转换为 RGB
* @param hex - 十六进制颜色代码 (例如: #2b2e3d)
* @returns - RGB 颜色字符串 (例如: 43, 46, 61)
*/
function hexToRgb(hex: string) {
// 移除前导 #
hex = hex.replace(/^#/, "");
// 处理 3 位和 6 位十六进制颜色
if (hex.length === 4) {
hex = hex
.split("")
.map((char: any, index: number) => (index > 0 ? char + char : char))
.join("");
}
const bigint = parseInt(hex, 16);
return [(bigint >> 16) & 255, (bigint >> 8) & 255, bigint & 255].join(", ");
}
// 使用说明
const doc = computed(() => {
const { type, condition } = props.item;
switch (type) {
case 0:
return `${condition?.fullAmount}可用`;
}
});
const couponStyle = computed(() => {
const { color } = props;
const rgbaColor = hexToRgb(color);
// 返回样式对象
return {
"--coupon-color": rgbaColor,
};
});
</script>
<style lang="scss" scoped>
.fix-coupon {
box-sizing: border-box;
overflow: hidden;
}
.coupon-activity {
display: flex;
position: relative;
height: 160rpx;
letter-spacing: 1rpx;
.a {
background: linear-gradient(
140deg,
rgba(var(--coupon-color), 0.75),
rgba(var(--coupon-color), 1)
);
height: 140rpx;
width: calc(100% - 250rpx);
border-radius: 12rpx;
position: absolute;
left: 24rpx;
bottom: 1rpx;
z-index: 2;
color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24rpx;
box-sizing: border-box;
.name {
display: block;
font-size: 28rpx;
font-weight: 500;
}
.desc {
font-size: 20rpx;
color: #ccc;
}
.tag {
padding: 2rpx 10rpx;
border-radius: 4rpx;
background-color: #eb10ab;
color: #fff;
font-size: 20rpx;
margin-right: 16rpx;
}
}
.b {
height: 160rpx;
width: 220rpx;
background-color: #e2e2e2;
box-sizing: border-box;
position: absolute;
right: 24rpx;
bottom: 0;
border-radius: 12rpx;
z-index: 3;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.amount {
font-size: 60rpx;
font-weight: bold;
line-height: 1;
color: rgba(var(--coupon-color), 1);
&::after {
content: "元";
font-size: 48rpx;
position: relative;
top: -4rpx;
}
}
.doc {
font-size: 22rpx;
color: #666;
}
}
.c {
content: "";
display: block;
height: 40rpx;
width: 40rpx;
background-color: #868686;
border-radius: 40rpx;
z-index: 1;
position: absolute;
right: 216rpx;
top: 2rpx;
}
}
</style>