更新项目配置和添加小程序模块
- 修改 ArticleController.java - 更新 application.yml 配置 - 更新 frontend/.env.production 环境配置 - 添加 single_uniapp22miao 小程序模块 - 添加 logs 目录
This commit is contained in:
849
single_uniapp22miao/pages/integral/detail.vue
Normal file
849
single_uniapp22miao/pages/integral/detail.vue
Normal file
@@ -0,0 +1,849 @@
|
||||
<template>
|
||||
<view class="goods-detail">
|
||||
<!-- 顶部导航栏 -->
|
||||
<view class="nav-bar">
|
||||
<view class="nav-back" @click="goBack">
|
||||
<text class="iconfont icon-fanhui"></text>
|
||||
</view>
|
||||
<text class="nav-title">商品详情</text>
|
||||
<view class="nav-right"></view>
|
||||
</view>
|
||||
|
||||
<!-- 商品图片轮播 -->
|
||||
<swiper
|
||||
class="goods-swiper"
|
||||
:indicator-dots="true"
|
||||
indicator-color="rgba(0,0,0,0.3)"
|
||||
indicator-active-color="#FF4D4F"
|
||||
>
|
||||
<swiper-item v-for="(image, index) in sliderImage" :key="index">
|
||||
<image
|
||||
:src="image"
|
||||
class="swiper-image"
|
||||
mode="aspectFill"
|
||||
@click="previewImage(index)"
|
||||
/>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<view class="wrapper" v-if="attr.productSelect">
|
||||
<view class="share-section">
|
||||
<view class="money-box">
|
||||
<text class="points-symbol">积分</text>
|
||||
<text class="points-num">{{ attr.productSelect.price || 0 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="introduce">{{ productInfo.storeName }}</view>
|
||||
|
||||
<!-- <view class="label">
|
||||
<view>原价:¥{{ attr.productSelect.otPrice || 0 }}</view>
|
||||
<view>库存:{{ attr.productSelect.stock || 0 }}{{ productInfo.unitName }}</view>
|
||||
<view>销量:{{ Number(productInfo.sales) + Number(productInfo.ficti) }}{{ productInfo.unitName }}</view>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<!-- 规格选择 -->
|
||||
<view class="attribute" @click="selecAttr">
|
||||
<view class="attr-row">
|
||||
<view class="attr-text">{{attrTxt}}:<text class="selected-attr">{{attrValue}}</text></view>
|
||||
<view class="iconfont icon-jiantou arrow-right"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 属性选择组件 -->
|
||||
<productWindow
|
||||
:attr="attr"
|
||||
:isShow='1'
|
||||
:iSplus='1'
|
||||
@myevent="onMyEvent"
|
||||
@ChangeAttr="ChangeAttr"
|
||||
@ChangeCartNum="ChangeCartNum"
|
||||
@attrVal="attrVal"
|
||||
@iptCartNum="iptCartNum">
|
||||
</productWindow>
|
||||
|
||||
<!-- 商品详情 -->
|
||||
<view class="detail-section">
|
||||
<view class="detail-info-list" v-if="attr.productSelect">
|
||||
<view class="detail-item">库存:{{ attr.productSelect.stock || 0 }}件</view>
|
||||
<!-- <view class="detail-item">已兑换:{{ Number(productInfo.sales) + Number(productInfo.ficti) }}件</view> -->
|
||||
</view>
|
||||
<view class="detail-content">
|
||||
<rich-text :nodes="description" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 浮动购物车按钮 -->
|
||||
<view class="floating-cart animated" :class="animated ? 'bounceIn' : ''" @click="goToCart">
|
||||
<view class='iconfont icon-gouwuche1'>
|
||||
<text v-if="Math.floor(CartCount) > 0" class='cart-badge'>{{CartCount}}</text>
|
||||
</view>
|
||||
<!-- <view class="cart-text">购物车</view> -->
|
||||
</view>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="bottom-bar safe-area-inset-bottom">
|
||||
<view class="btn-group">
|
||||
<view class="btn-cart" @click="onCartAdd">
|
||||
<text>加入购物车</text>
|
||||
</view>
|
||||
<view
|
||||
class="btn-buy"
|
||||
:class="{ disabled: attr.productSelect && attr.productSelect.stock <= 0 }"
|
||||
@click="onExchange"
|
||||
>
|
||||
<text>{{ exchangeButtonText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { collectIntegralGoods } from '@/api/miao.js'
|
||||
import { getProductDetail, postCartAdd } from '@/api/store.js';
|
||||
import { getCartCounts } from '@/api/order.js';
|
||||
import { toLogin } from '@/libs/login.js';
|
||||
import { mapGetters } from "vuex";
|
||||
import productWindow from '@/components/productWindow';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
productWindow
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
goodsId: 0,
|
||||
productInfo: {
|
||||
sales: 0,
|
||||
ficti: 0,
|
||||
unitName: '件'
|
||||
},
|
||||
productValue: {},
|
||||
skuArr: [],
|
||||
sliderImage: [],
|
||||
attr: {
|
||||
cartAttr: false,
|
||||
productAttr: [],
|
||||
productSelect: {
|
||||
price: 0,
|
||||
stock: 0,
|
||||
otPrice: 0,
|
||||
unique: '',
|
||||
cart_num: 1
|
||||
}
|
||||
},
|
||||
attrValue: '',
|
||||
attrTxt: '请选择',
|
||||
reply: [],
|
||||
replyCount: 0,
|
||||
replyChance: 0,
|
||||
description: '',
|
||||
isOpen: false, // 是否打开过属性选择器
|
||||
CartCount: 0, // 购物车数量
|
||||
animated: false // 购物车动画
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters(['isLogin', 'uid']),
|
||||
|
||||
exchangeButtonText() {
|
||||
if (this.attr.productSelect && this.attr.productSelect.stock <= 0) {
|
||||
return '库存不足'
|
||||
}
|
||||
return '立即兑换'
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
if (options.id) {
|
||||
this.goodsId = parseInt(options.id)
|
||||
this.getDetail()
|
||||
}
|
||||
},
|
||||
|
||||
onShow() {
|
||||
// 从兑换页面返回时刷新数据
|
||||
if (this.goodsId) {
|
||||
this.getDetail()
|
||||
}
|
||||
// 获取购物车数量
|
||||
this.getCartCount();
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 获取商品详情
|
||||
getDetail() {
|
||||
let that = this;
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
})
|
||||
getProductDetail(that.goodsId, 1).then(res => {
|
||||
let productInfo = res.data.productInfo;
|
||||
// 字符串数组转数组;
|
||||
let arrayImg = productInfo.sliderImage;
|
||||
let sliderImage = JSON.parse(arrayImg);
|
||||
that.$set(that, 'sliderImage', sliderImage);
|
||||
that.$set(that, 'productInfo', productInfo);
|
||||
that.$set(that, 'description', productInfo.content);
|
||||
that.$set(that.attr, 'productAttr', res.data.productAttr);
|
||||
that.$set(that, 'productValue', res.data.productValue);
|
||||
that.skuArr = [];
|
||||
for (let key in res.data.productValue) {
|
||||
let obj = res.data.productValue[key];
|
||||
that.skuArr.push(obj)
|
||||
}
|
||||
|
||||
let productAttr = that.attr.productAttr.map(item => {
|
||||
return {
|
||||
attrName: item.attrName,
|
||||
attrValues: item.attrValues.split(','),
|
||||
id: item.id,
|
||||
isDel: item.isDel,
|
||||
productId: item.productId,
|
||||
type: item.type
|
||||
}
|
||||
});
|
||||
that.$set(that.attr, 'productAttr', productAttr);
|
||||
|
||||
that.DefaultSelect();
|
||||
uni.hideLoading();
|
||||
}).catch(err => {
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: err.msg || '加载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 默认选中属性
|
||||
*
|
||||
*/
|
||||
DefaultSelect: function() {
|
||||
let productAttr = this.attr.productAttr;
|
||||
let value = [];
|
||||
//默认选中每种规格的第一个
|
||||
for (let key in this.productValue) {
|
||||
if (this.productValue[key].stock > 0) {
|
||||
value = this.attr.productAttr.length ? key.split(",") : [];
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
this.$set(productAttr[i], "index", value[i]);
|
||||
}
|
||||
|
||||
//sort();排序函数:数字-英文-汉字;
|
||||
let productSelect = this.productValue[value.join(",")];
|
||||
if (productSelect && productAttr.length) {
|
||||
this.$set(this.attr.productSelect, "storeName", this.productInfo.storeName);
|
||||
this.$set(this.attr.productSelect, "image", productSelect.image);
|
||||
this.$set(this.attr.productSelect, "price", productSelect.price);
|
||||
this.$set(this.attr.productSelect, "stock", productSelect.stock);
|
||||
this.$set(this.attr.productSelect, "unique", productSelect.id);
|
||||
this.$set(this.attr.productSelect, "cart_num", 1);
|
||||
this.$set(this.attr.productSelect, "vipPrice", productSelect.vipPrice);
|
||||
this.$set(this.attr.productSelect, 'otPrice', productSelect.otPrice);
|
||||
this.$set(this, "attrValue", value.join(","));
|
||||
this.$set(this, "attrTxt", "已选择");
|
||||
} else if (!productSelect && productAttr.length) {
|
||||
this.$set(this.attr.productSelect, "storeName", this.productInfo.storeName);
|
||||
this.$set(this.attr.productSelect, "image", this.productInfo.image);
|
||||
this.$set(this.attr.productSelect, "price", this.productInfo.price);
|
||||
this.$set(this.attr.productSelect, "stock", 0);
|
||||
this.$set(this.attr.productSelect, "unique", this.productInfo.id);
|
||||
this.$set(this.attr.productSelect, "cart_num", 1);
|
||||
this.$set(this.attr.productSelect, "vipPrice", this.productInfo.vipPrice);
|
||||
this.$set(this.attr.productSelect, 'otPrice', this.productInfo.otPrice);
|
||||
this.$set(this, "attrValue", "");
|
||||
this.$set(this, "attrTxt", "请选择");
|
||||
} else if (!productSelect && !productAttr.length) {
|
||||
this.$set(this.attr.productSelect, "storeName", this.productInfo.storeName);
|
||||
this.$set(this.attr.productSelect, "image", this.productInfo.image);
|
||||
this.$set(this.attr.productSelect, "price", this.productInfo.price);
|
||||
this.$set(this.attr.productSelect, "stock", this.productInfo.stock);
|
||||
this.$set(this.attr.productSelect, "unique", this.productInfo.id || "");
|
||||
this.$set(this.attr.productSelect, "cart_num", 1);
|
||||
this.$set(this.attr.productSelect, "vipPrice", this.productInfo.vipPrice);
|
||||
this.$set(this.attr.productSelect, 'otPrice', this.productInfo.otPrice);
|
||||
this.$set(this, "attrValue", "");
|
||||
this.$set(this, "attrTxt", "已选择");
|
||||
}
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage(index) {
|
||||
uni.previewImage({
|
||||
urls: this.sliderImage,
|
||||
current: index
|
||||
})
|
||||
},
|
||||
|
||||
// 打开属性选择器
|
||||
selecAttr() {
|
||||
this.$set(this.attr, 'cartAttr', true);
|
||||
this.$set(this, 'isOpen', true);
|
||||
},
|
||||
|
||||
// 关闭属性选择器
|
||||
onMyEvent() {
|
||||
this.$set(this.attr, 'cartAttr', false);
|
||||
this.$set(this, 'isOpen', false);
|
||||
},
|
||||
|
||||
// 属性变动赋值
|
||||
ChangeAttr(res) {
|
||||
let productSelect = this.productValue[res];
|
||||
if (productSelect) {
|
||||
this.$set(this.attr.productSelect, "image", productSelect.image);
|
||||
this.$set(this.attr.productSelect, "price", productSelect.price);
|
||||
this.$set(this.attr.productSelect, "stock", productSelect.stock);
|
||||
this.$set(this.attr.productSelect, "unique", productSelect.id);
|
||||
this.$set(this.attr.productSelect, "cart_num", 1);
|
||||
this.$set(this.attr.productSelect, "vipPrice", productSelect.vipPrice);
|
||||
this.$set(this.attr.productSelect, 'otPrice', productSelect.otPrice);
|
||||
this.$set(this, "attrValue", res);
|
||||
this.$set(this, "attrTxt", "已选择");
|
||||
} else {
|
||||
this.$set(this.attr.productSelect, "image", this.productInfo.image);
|
||||
this.$set(this.attr.productSelect, "price", this.productInfo.price);
|
||||
this.$set(this.attr.productSelect, "stock", 0);
|
||||
this.$set(this.attr.productSelect, "unique", this.productInfo.id);
|
||||
this.$set(this.attr.productSelect, "cart_num", 1);
|
||||
this.$set(this.attr.productSelect, "vipPrice", this.productInfo.vipPrice);
|
||||
this.$set(this.attr.productSelect, 'otPrice', this.productInfo.otPrice);
|
||||
this.$set(this, "attrValue", "");
|
||||
this.$set(this, "attrTxt", "请选择");
|
||||
}
|
||||
},
|
||||
|
||||
// 购物车数量加减
|
||||
ChangeCartNum(changeValue) {
|
||||
let productSelect = this.productValue[this.attrValue];
|
||||
if (productSelect === undefined && !this.attr.productAttr.length)
|
||||
productSelect = this.attr.productSelect;
|
||||
if (productSelect === undefined) return;
|
||||
|
||||
let stock = productSelect.stock || 0;
|
||||
let num = this.attr.productSelect;
|
||||
if (changeValue) {
|
||||
num.cart_num++;
|
||||
if (num.cart_num > stock) {
|
||||
this.$set(this.attr.productSelect, "cart_num", stock);
|
||||
}
|
||||
} else {
|
||||
num.cart_num--;
|
||||
if (num.cart_num < 1) {
|
||||
this.$set(this.attr.productSelect, "cart_num", 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 属性值选择
|
||||
attrVal(val) {
|
||||
this.$set(this.attr.productAttr[val.indexw], 'index', this.attr.productAttr[val.indexw].attrValues[val.indexn]);
|
||||
},
|
||||
|
||||
// 购物车手动填写
|
||||
iptCartNum(e) {
|
||||
this.$set(this.attr.productSelect, 'cart_num', e ? e : 1);
|
||||
},
|
||||
|
||||
// 加入购物车
|
||||
onCartAdd() {
|
||||
// 检查是否登录
|
||||
if (this.isLogin === false) {
|
||||
toLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用统一的处理方法,1 表示加入购物车
|
||||
this.goCat(1);
|
||||
},
|
||||
|
||||
// 立即兑换
|
||||
onExchange() {
|
||||
// 检查库存
|
||||
if (this.attr.productSelect && this.attr.productSelect.stock <= 0) {
|
||||
uni.showToast({
|
||||
title: '库存不足',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否登录
|
||||
if (this.isLogin === false) {
|
||||
toLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用统一的处理方法,0 表示立即购买
|
||||
this.goCat(0);
|
||||
},
|
||||
|
||||
/**
|
||||
* 统一处理加入购物车和立即兑换
|
||||
* @param {Number} num 1-加入购物车 0-立即购买/兑换
|
||||
*/
|
||||
goCat(num) {
|
||||
let that = this;
|
||||
let productSelect = that.productValue[this.attrValue];
|
||||
|
||||
// 打开属性选择器
|
||||
if (that.attrValue) {
|
||||
// 默认选中了属性,但是没有打开过属性弹窗还是自动打开让用户查看默认选中的属性
|
||||
that.attr.cartAttr = !that.isOpen ? true : false;
|
||||
} else {
|
||||
if (that.isOpen) that.attr.cartAttr = true;
|
||||
else that.attr.cartAttr = !that.attr.cartAttr;
|
||||
}
|
||||
|
||||
// 只有关闭属性弹窗时进行操作
|
||||
if (that.attr.cartAttr === true && that.isOpen === false) {
|
||||
return (that.isOpen = true);
|
||||
}
|
||||
|
||||
// 如果有属性,没有选择或库存为0,提示用户选择
|
||||
if (
|
||||
that.attr.productAttr.length &&
|
||||
productSelect &&
|
||||
productSelect.stock === 0 &&
|
||||
that.isOpen === true
|
||||
) {
|
||||
uni.showToast({
|
||||
title: "产品库存不足,请选择其它",
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 执行对应操作
|
||||
if (num === 1) {
|
||||
// 加入购物车
|
||||
let q = {
|
||||
productId: parseFloat(that.goodsId),
|
||||
cartNum: parseFloat(that.attr.productSelect.cart_num),
|
||||
isNew: false,
|
||||
productAttrUnique: that.attr.productSelect !== undefined ?
|
||||
that.attr.productSelect.unique : that.productInfo.id
|
||||
};
|
||||
|
||||
postCartAdd(q).then(function(res) {
|
||||
that.isOpen = false;
|
||||
that.attr.cartAttr = false;
|
||||
uni.showToast({
|
||||
title: "添加购物车成功",
|
||||
icon: 'success'
|
||||
});
|
||||
// 更新购物车数量
|
||||
that.getCartCount(true);
|
||||
}).catch(res => {
|
||||
that.isOpen = false;
|
||||
that.attr.cartAttr = false;
|
||||
uni.showToast({
|
||||
title: res.msg || '添加失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// 立即兑换 - 直接跳转到积分商城下单页面
|
||||
this.goToConfirm();
|
||||
}
|
||||
},
|
||||
|
||||
// 直接跳转到积分商城下单页面
|
||||
goToConfirm() {
|
||||
// 保存商品信息到缓存
|
||||
const goodsInfo = {
|
||||
id: this.goodsId,
|
||||
name: this.productInfo.storeName,
|
||||
storeName: this.productInfo.storeName,
|
||||
image: this.attr.productSelect.image || this.productInfo.image,
|
||||
pic: this.attr.productSelect.image || this.productInfo.image,
|
||||
points: this.attr.productSelect.price || this.productInfo.price,
|
||||
integral: this.attr.productSelect.price || this.productInfo.price,
|
||||
quantity: this.attr.productSelect.cart_num || 1,
|
||||
attrValueId: this.attr.productSelect.unique || '',
|
||||
unique: this.attr.productSelect.unique || '',
|
||||
productAttrUnique: this.attr.productSelect.unique || '',
|
||||
sku: this.attrValue || ''
|
||||
};
|
||||
|
||||
uni.setStorageSync('buy_now_goods', goodsInfo);
|
||||
|
||||
this.isOpen = false;
|
||||
this.attr.cartAttr = false;
|
||||
|
||||
// 跳转到积分商城下单页面
|
||||
uni.navigateTo({
|
||||
url: `/pages/integral/confirm?id=${this.goodsId}&quantity=${this.attr.productSelect.cart_num || 1}`
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取购物车数量
|
||||
* @param {Boolean} isAnima 是否展示购物车动画和重置属性
|
||||
*/
|
||||
getCartCount(isAnima) {
|
||||
let that = this;
|
||||
const isLogin = that.isLogin;
|
||||
if (isLogin) {
|
||||
getCartCounts(true, 'total').then(res => {
|
||||
that.CartCount = res.data.count;
|
||||
// 加入购物车后重置属性
|
||||
if (isAnima) {
|
||||
that.animated = true;
|
||||
setTimeout(function() {
|
||||
that.animated = false;
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 跳转购物车
|
||||
goToCart() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/integral/cart',
|
||||
fail: (err) => {
|
||||
console.error('跳转购物车失败:', err);
|
||||
uni.showToast({
|
||||
title: '跳转失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 返回上一页
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.goods-detail {
|
||||
min-height: 100vh;
|
||||
background-color: #F5F5F5;
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
// 顶部导航栏
|
||||
.nav-bar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 113.344rpx;
|
||||
background: linear-gradient(180deg, rgba(0, 0, 0, 0.4) 0%, rgba(0, 0, 0, 0) 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 31.996rpx;
|
||||
z-index: 200;
|
||||
padding-top: constant(safe-area-inset-top);
|
||||
padding-top: env(safe-area-inset-top);
|
||||
}
|
||||
|
||||
.nav-back {
|
||||
width: 72rpx;
|
||||
height: 64rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 50%;
|
||||
|
||||
.iconfont {
|
||||
font-size: 36rpx;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
flex: 1;
|
||||
font-size: 32rpx;
|
||||
color: #FFFFFF;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
line-height: 48rpx;
|
||||
}
|
||||
|
||||
.nav-right {
|
||||
width: 72rpx;
|
||||
height: 64rpx;
|
||||
}
|
||||
|
||||
// 图片轮播
|
||||
.goods-swiper {
|
||||
width: 100%;
|
||||
height: 750rpx;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.swiper-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// 仿照 goods_details 的 wrapper 样式
|
||||
.wrapper {
|
||||
background-color: #fff;
|
||||
margin: 20rpx;
|
||||
padding: 30rpx;
|
||||
border-radius: 14rpx;
|
||||
}
|
||||
|
||||
.share-section {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.money-box {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
color: #FF4D4F;
|
||||
}
|
||||
|
||||
.points-num {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.points-symbol {
|
||||
font-size: 24rpx;
|
||||
margin-right: 4rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.introduce {
|
||||
font-size: 32rpx;
|
||||
color: #282828;
|
||||
font-weight: bold;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
// 仿照 goods_details 的 attribute 样式
|
||||
.attribute {
|
||||
background-color: #fff;
|
||||
margin: 20rpx;
|
||||
padding: 30rpx;
|
||||
border-radius: 14rpx;
|
||||
}
|
||||
|
||||
.attr-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.attr-text {
|
||||
font-size: 28rpx;
|
||||
color: #282828;
|
||||
width: 600rpx;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.selected-attr {
|
||||
color: #666;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.arrow-right {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
// 兑换规则
|
||||
.rules-section,
|
||||
.detail-section {
|
||||
margin: 20rpx;
|
||||
padding: 30rpx;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.detail-info-list {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 16rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
// 底部操作栏
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #FFFFFF;
|
||||
border-top: 1px solid #EEEEEE;
|
||||
padding: 20rpx 30rpx;
|
||||
z-index: 100;
|
||||
padding-bottom: calc(20rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
// 浮动购物车按钮
|
||||
.floating-cart {
|
||||
position: fixed;
|
||||
right: 30rpx;
|
||||
bottom: calc(240rpx + constant(safe-area-inset-bottom));
|
||||
bottom: calc(240rpx + env(safe-area-inset-bottom));
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.15);
|
||||
z-index: 101;
|
||||
|
||||
.iconfont {
|
||||
font-size: 44rpx;
|
||||
color: #FF4D4F;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cart-badge {
|
||||
position: absolute;
|
||||
top: -8rpx;
|
||||
right: -16rpx;
|
||||
background: linear-gradient(90deg, #FF6900 0%, #FF4D4F 100%);
|
||||
color: #FFFFFF;
|
||||
font-size: 18rpx;
|
||||
padding: 2rpx 8rpx 3rpx;
|
||||
border-radius: 200rpx;
|
||||
min-width: 28rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cart-text {
|
||||
font-size: 18rpx;
|
||||
color: #666666;
|
||||
margin-top: 2rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.animated {
|
||||
animation-duration: 0.5s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.bounceIn {
|
||||
animation-name: bounceIn;
|
||||
}
|
||||
|
||||
@keyframes bounceIn {
|
||||
from,
|
||||
20%,
|
||||
40%,
|
||||
60%,
|
||||
80%,
|
||||
to {
|
||||
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
}
|
||||
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale3d(0.3, 0.3, 0.3);
|
||||
}
|
||||
|
||||
20% {
|
||||
transform: scale3d(1.1, 1.1, 1.1);
|
||||
}
|
||||
|
||||
40% {
|
||||
transform: scale3d(0.9, 0.9, 0.9);
|
||||
}
|
||||
|
||||
60% {
|
||||
opacity: 1;
|
||||
transform: scale3d(1.03, 1.03, 1.03);
|
||||
}
|
||||
|
||||
80% {
|
||||
transform: scale3d(0.97, 0.97, 0.97);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.btn-cart,
|
||||
.btn-buy {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.btn-cart {
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #EEEEEE;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.btn-buy {
|
||||
background: linear-gradient(90deg, #FF6900 0%, #FF4D4F 100%);
|
||||
color: #FFFFFF;
|
||||
|
||||
&.disabled {
|
||||
background: #CCCCCC;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
.detail-content img, .detail-content image{
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user