|
|
@@ -1,646 +0,0 @@
|
|
|
-<template>
|
|
|
- <view class="app-main app-content">
|
|
|
-
|
|
|
- <view class="c_header" :class="myClass">
|
|
|
- <view class="header_inside">
|
|
|
- <image :src="shopImg"></image>
|
|
|
- <view class="shop_info">
|
|
|
- <view class="shop_title">{{shopName}}</view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 搜索框和花材绿植按钮区域 -->
|
|
|
- <view class="search-wrap">
|
|
|
- <view class="search-bar">
|
|
|
- <app-search-module
|
|
|
- v-model="searchText"
|
|
|
- :placeholder="isSearching ? '正在搜索...' : '搜索商品名称'"
|
|
|
- @input="searchFn"
|
|
|
- :height="66"
|
|
|
- :fontSize="28"
|
|
|
- />
|
|
|
- </view>
|
|
|
- <view class="buy-material-container">
|
|
|
- <button class="buy-material-btn" @click="buyProduct()">
|
|
|
- <view class="btn-content">
|
|
|
- <text class="btn-text">花材绿植</text>
|
|
|
- </view>
|
|
|
- </button>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <!-- 搜索状态提示 -->
|
|
|
- <view v-if="isSearching" class="search-loading">
|
|
|
- <text class="loading-text">正在搜索...</text>
|
|
|
- </view>
|
|
|
-
|
|
|
- <scroll-view scroll-y scroll-with-animation class="tab-view" :scroll-top="scrollTop">
|
|
|
- <view v-for="(item,index) in tabbar" :key="index" class="tab-bar-item" :class="[!isSearchMode && currentTab==index ? 'active' : '']" :data-current="index" @tap.stop="swichNav($event ,item)" >
|
|
|
- <text>{{item.categoryName}}</text>
|
|
|
- </view>
|
|
|
- <view style="height:150upx"></view>
|
|
|
- </scroll-view>
|
|
|
-
|
|
|
- <!-- 搜索结果展示区域 -->
|
|
|
- <scroll-view v-if="isSearchMode" scroll-y class="right-box" @scrolltolower="reachBottom">
|
|
|
- <view class="page-view" v-if="!$util.isEmpty(list.data)" >
|
|
|
- <view class="goods-list" v-for="(items) in list.data" :key="items.id" @click="toBuy(items)" >
|
|
|
- <view class="img-blo">
|
|
|
- <image :src="items.smallCover" mode="aspectFill" ></image>
|
|
|
- </view>
|
|
|
- <view class="goods-det">
|
|
|
- <view class="goods-det-top">
|
|
|
- <view class="goods-name">{{ items.name }}</view>
|
|
|
- <view class="goods-sales"></view>
|
|
|
- </view>
|
|
|
- <view class="goods-price">已售 {{ items.actualSold?parseInt(items.actualSold):0 }}</view>
|
|
|
- <view class="buy-btn">查看</view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <block v-else>
|
|
|
- <app-wrapper-empty
|
|
|
- :title="getEmptyTitle()"
|
|
|
- :is-empty="$util.isEmpty(list.data)"
|
|
|
- />
|
|
|
- </block>
|
|
|
- </scroll-view>
|
|
|
-
|
|
|
- <!-- 分类商品展示区域 -->
|
|
|
- <block v-for="(item,index) in tabbar" :key="index" >
|
|
|
- <scroll-view scroll-y class="right-box" @scrolltolower="reachBottom" v-if="!isSearchMode && currentTab==index" >
|
|
|
- <view class="page-view" v-if="!$util.isEmpty(list.data)" >
|
|
|
- <view class="goods-list" v-for="(items) in list.data" :key="items.id" @click="toBuy(items)" >
|
|
|
- <view class="img-blo">
|
|
|
- <image :src="items.smallCover" mode="aspectFill" ></image>
|
|
|
- </view>
|
|
|
- <view class="goods-det">
|
|
|
- <view class="goods-det-top">
|
|
|
- <view class="goods-name">{{ items.name }}</view>
|
|
|
- <view class="goods-sales"></view>
|
|
|
- </view>
|
|
|
- <view class="goods-price">已售 {{ items.actualSold?parseInt(items.actualSold):0 }}</view>
|
|
|
- <view class="buy-btn">查看</view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <block v-else>
|
|
|
- <app-wrapper-empty
|
|
|
- :title="getEmptyTitle()"
|
|
|
- :is-empty="$util.isEmpty(list.data)"
|
|
|
- />
|
|
|
- </block>
|
|
|
- </scroll-view>
|
|
|
- </block>
|
|
|
-
|
|
|
- <wangCg :loginStyle.sync="globalLoginStyle" @goToLogin="loginTo()"></wangCg>
|
|
|
- </view>
|
|
|
- </template>
|
|
|
- <script>
|
|
|
- import { mapGetters } from 'vuex'
|
|
|
- import AppImg from '@/components/app-img'
|
|
|
- import wangCg from "@/components/wangCg"
|
|
|
- import AppWrapperEmpty from '@/components/app-wrapper-empty'
|
|
|
- import AppSearchModule from '@/components/item/module/app-search'
|
|
|
- import { getClass, getNonPriceList } from '@/api/category'
|
|
|
- import { list,share } from '@/mixins'
|
|
|
- import { getInfo } from "@/api/shop"
|
|
|
- export default {
|
|
|
- name: 'category',
|
|
|
- components: {
|
|
|
- AppWrapperEmpty,
|
|
|
- AppImg,
|
|
|
- wangCg,
|
|
|
- AppSearchModule
|
|
|
- },
|
|
|
- mixins: [list, share],
|
|
|
- data () {
|
|
|
- return {
|
|
|
- tabbar: [],
|
|
|
- height: 0,
|
|
|
- currentTab: 0,
|
|
|
- scrollTop: 0,
|
|
|
- form: {
|
|
|
- categoryId: ''
|
|
|
- },
|
|
|
- currentTabIndex: 1,
|
|
|
- myClass: 'fadeIn',
|
|
|
- shopName:'',
|
|
|
- shopImg:'',
|
|
|
- hdId:0,
|
|
|
- searchText: '', // 搜索文本
|
|
|
- searchTimer: null, // 搜索防抖定时器
|
|
|
- isSearchMode: false, // 是否为搜索模式
|
|
|
- isSearching: false, // 是否正在搜索
|
|
|
- lastSearchText: '' // 上次搜索的文本,用于优化
|
|
|
- }
|
|
|
- },
|
|
|
- computed: {
|
|
|
- ...mapGetters({ loginInfo:"getLoginInfo" })
|
|
|
- },
|
|
|
- onShareAppMessage(res) {
|
|
|
- return {
|
|
|
- title: '花束花礼',
|
|
|
- desc: "",
|
|
|
- path: "pages/home/category?account="+this.option.account,
|
|
|
- }
|
|
|
- },
|
|
|
- onShow(){
|
|
|
- if(!this.$util.isEmpty(this.loginInfo)){
|
|
|
- this.globalLoginStyle = 1
|
|
|
- }else{
|
|
|
- this.globalLoginStyle = 0
|
|
|
- }
|
|
|
- },
|
|
|
- onUnload() {
|
|
|
- // 清理搜索定时器
|
|
|
- if (this.searchTimer) {
|
|
|
- clearTimeout(this.searchTimer);
|
|
|
- this.searchTimer = null;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- watch: {
|
|
|
- loginInfo: {
|
|
|
- deep: true,
|
|
|
- handler: function(newVal) {
|
|
|
- if(!this.$util.isEmpty(newVal)){
|
|
|
- this.globalLoginStyle = 1
|
|
|
- }else{
|
|
|
- this.globalLoginStyle = 0
|
|
|
- }
|
|
|
- },
|
|
|
- immediate:true
|
|
|
- }
|
|
|
- },
|
|
|
- methods: {
|
|
|
- toBuy(item){
|
|
|
- let account = this.option.account?this.option.account:0
|
|
|
- this.$util.pageTo({url:"/pages/goods/detail?id="+item.id+'&hdId='+this.hdId+'&categoryId='+this.form.categoryId+'&account='+account})
|
|
|
- },
|
|
|
- buyProduct(){
|
|
|
- let account = this.option.account?this.option.account:0
|
|
|
- this.$util.pageTo({url:"/pages/item/item?account="+account+'&hdId='+this.hdId,type:2})
|
|
|
- },
|
|
|
- loginTo() {
|
|
|
- let account = this.option.account?this.option.account:0
|
|
|
- this.$util.pageTo({url:"/pages/login/index?needBack=1&account="+account})
|
|
|
- },
|
|
|
- init(){
|
|
|
- this.hdId = this.option.hdId ? this.option.hdId : 0
|
|
|
- this.classInit()
|
|
|
- getInfo({hdId:this.hdId}).then(res=>{
|
|
|
- if(res.code == 1){
|
|
|
- if(res.data.info && res.data.info.merchantName){
|
|
|
- let sjName = res.data.info.merchantName
|
|
|
- let shopName = res.data.info.shopName ? res.data.info.shopName : '首店'
|
|
|
- let name = shopName == '首店' ? sjName : sjName+' '+shopName
|
|
|
- this.shopName = name
|
|
|
- this.shopImg = res.data.info.avatar
|
|
|
- }
|
|
|
-
|
|
|
- if(res.data.hd && Number(res.data.hd.id) > 0){
|
|
|
- if(Number(this.hdId) == 0){
|
|
|
- this.hdId = res.data.hd.id
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
- // 搜索输入处理(防抖)
|
|
|
- searchFn() {
|
|
|
- console.log('searchFn----------', this.searchText, 'lastSearchText:', this.lastSearchText)
|
|
|
-
|
|
|
- // 清除之前的定时器
|
|
|
- if (this.searchTimer) {
|
|
|
- clearTimeout(this.searchTimer)
|
|
|
- this.searchTimer = null
|
|
|
- }
|
|
|
-
|
|
|
- // 如果搜索文本为空
|
|
|
- if (this.$util.isEmpty(this.searchText)) {
|
|
|
- // 如果之前也是空文本(首次点击或焦点清空),跳过搜索
|
|
|
- if (this.$util.isEmpty(this.lastSearchText)) {
|
|
|
- console.log('搜索文本为空且之前也为空,跳过搜索')
|
|
|
- return
|
|
|
- }
|
|
|
- // 如果之前有搜索文本,现在清空了,则恢复分类筛选
|
|
|
- this.clearSearch()
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 如果搜索文本与上次相同,不重复搜索
|
|
|
- if (this.searchText === this.lastSearchText) {
|
|
|
- console.log('搜索文本未变化,跳过搜索')
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 设置防抖定时器,1秒后执行搜索
|
|
|
- this.searchTimer = setTimeout(() => {
|
|
|
- this.performSearch()
|
|
|
- }, 1000)
|
|
|
- },
|
|
|
-
|
|
|
- // 执行搜索
|
|
|
- performSearch() {
|
|
|
- if (this.$util.isEmpty(this.searchText)) {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- console.log('执行搜索:', this.searchText)
|
|
|
-
|
|
|
- this.isSearchMode = true
|
|
|
- this.isSearching = true
|
|
|
- this.lastSearchText = this.searchText
|
|
|
- this.resetList()
|
|
|
- this.searchGoods()
|
|
|
- },
|
|
|
-
|
|
|
- // 清空搜索,恢复分类筛选
|
|
|
- clearSearch() {
|
|
|
- console.log('清空搜索,恢复分类筛选')
|
|
|
- this.isSearchMode = false
|
|
|
- this.isSearching = false
|
|
|
- this.lastSearchText = ''
|
|
|
-
|
|
|
- // 确保搜索框内容被清空
|
|
|
- this.$nextTick(() => {
|
|
|
- this.searchText = ''
|
|
|
- })
|
|
|
-
|
|
|
- this.resetList()
|
|
|
- this.getGoodList()
|
|
|
- },
|
|
|
-
|
|
|
- // 搜索商品
|
|
|
- searchGoods() {
|
|
|
- return getNonPriceList({
|
|
|
- searchText: this.searchText,
|
|
|
- page: this.list.page,
|
|
|
- pageSize: 10
|
|
|
- }).then(res => {
|
|
|
- this.isSearching = false
|
|
|
- this.completes(res)
|
|
|
- console.log('搜索成功,数据已加载')
|
|
|
- }).catch(err => {
|
|
|
- this.isSearching = false
|
|
|
- console.error('搜索失败:', err)
|
|
|
- this.$msg('搜索失败,请重试')
|
|
|
- })
|
|
|
- },
|
|
|
- reachBottom () {
|
|
|
- console.log('reachBottom----------', this.list.finished)
|
|
|
- if (this.list.finished == false && !this.isSearching) {
|
|
|
- // 根据是否为搜索模式决定调用哪个方法
|
|
|
- if (this.isSearchMode) {
|
|
|
- this.searchGoods().then(res => {
|
|
|
- uni.stopPullDownRefresh()
|
|
|
- });
|
|
|
- } else {
|
|
|
- this.getGoodList().then(res => {
|
|
|
- uni.stopPullDownRefresh()
|
|
|
- });
|
|
|
- }
|
|
|
- } else {
|
|
|
- uni.stopPullDownRefresh()
|
|
|
- }
|
|
|
- },
|
|
|
- async classInit () {
|
|
|
- this.getMyClass() .then(res => {
|
|
|
- this.getGoodList()
|
|
|
- })
|
|
|
- },
|
|
|
- // 分类
|
|
|
- getMyClass () {
|
|
|
- return getClass().then(res => {
|
|
|
- if(res.code && res.code == 1){
|
|
|
- this.form.categoryId = res.data[0].id
|
|
|
- this.tabbar = res.data
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
- // 列表
|
|
|
- getGoodList () {
|
|
|
- return getNonPriceList({ ...this.form, page: this.list.page,pageSize:10 }) .then(res => {
|
|
|
- // 处理商品列表数据,completes方法来自list混入
|
|
|
- // 该方法会处理分页数据,更新list对象的data、page、finished等属性
|
|
|
- // res包含接口返回的商品列表数据,completes方法会将数据添加到this.list.data中
|
|
|
- this.completes(res)
|
|
|
- })
|
|
|
- },
|
|
|
- // 点击标题切换当前页时改变样式
|
|
|
- swichNav (e, item) {
|
|
|
- let cur = e.currentTarget.dataset.current
|
|
|
- if (this.currentTab == cur && !this.isSearchMode) {
|
|
|
- return false
|
|
|
- } else {
|
|
|
- this.currentTab = cur
|
|
|
- this.form.categoryId = item.id
|
|
|
-
|
|
|
- // 切换分类时清空搜索状态
|
|
|
- this.clearSearchState()
|
|
|
- this.resetList()
|
|
|
- this.getGoodList()
|
|
|
- }
|
|
|
- },
|
|
|
- // 判断当前滚动超过一屏时,设置tab标题滚动条。
|
|
|
- checkCor () {
|
|
|
- let that = this
|
|
|
- // 这里计算按照实际情况进行修改,动态数据要进行动态分析
|
|
|
- // 思路:窗体高度/单个分类高度 200upx 转px计算 =>得到一屏幕所显示的个数,结合后台传回分类总数进行计算
|
|
|
- // 数据很多可以多次if判断然后进行滚动距离计算即可
|
|
|
- if (that.currentTab > 7) {
|
|
|
- that.scrollTop = 500
|
|
|
- } else {
|
|
|
- that.scrollTop = 0
|
|
|
- }
|
|
|
- },
|
|
|
- tabClick (index) {
|
|
|
- this.currentTabIndex = index
|
|
|
- },
|
|
|
-
|
|
|
- // 清空搜索状态(不触发数据重新加载)
|
|
|
- clearSearchState() {
|
|
|
- // 清除定时器
|
|
|
- if (this.searchTimer) {
|
|
|
- clearTimeout(this.searchTimer)
|
|
|
- this.searchTimer = null
|
|
|
- }
|
|
|
-
|
|
|
- // 重置搜索相关状态
|
|
|
- this.searchText = ''
|
|
|
- this.isSearchMode = false
|
|
|
- this.isSearching = false
|
|
|
- this.lastSearchText = ''
|
|
|
-
|
|
|
- // 确保搜索框内容被清空(强制更新)
|
|
|
- // this.$nextTick(() => {
|
|
|
- // this.searchText = ''
|
|
|
- // })
|
|
|
- },
|
|
|
-
|
|
|
- // 获取空状态提示文字
|
|
|
- getEmptyTitle() {
|
|
|
- if (this.isSearchMode && this.searchText) {
|
|
|
- return `未找到"${this.searchText}"相关商品`
|
|
|
- }
|
|
|
- return '暂无商品'
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- // 组件销毁时清理定时器
|
|
|
- beforeDestroy() {
|
|
|
- if (this.searchTimer) {
|
|
|
- clearTimeout(this.searchTimer)
|
|
|
- this.searchTimer = null
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- </script>
|
|
|
-
|
|
|
- <style lang="scss" scoped>
|
|
|
- .app-content {
|
|
|
- background-color: #fff;
|
|
|
-
|
|
|
- .c_header{
|
|
|
- width: 100vw;
|
|
|
- padding: 0 15upx;
|
|
|
- box-sizing: border-box;
|
|
|
- background: linear-gradient(to bottom,#3385FF, #fff);
|
|
|
- &>.header_inside{
|
|
|
- position: relative;
|
|
|
- height: 124upx;
|
|
|
- margin-top: 15upx;
|
|
|
- background: #fff;
|
|
|
- box-shadow: 0upx 1px 21px 0upx rgba(161, 166, 173, 0.4);
|
|
|
- border-radius: 20upx;
|
|
|
- padding: 35upx 30upx 30upx 30upx;
|
|
|
- box-sizing: border-box;
|
|
|
- &>image{
|
|
|
- height: 60upx;
|
|
|
- width: 60upx;
|
|
|
- display: inline-block;
|
|
|
- border-radius: 10upx;
|
|
|
- background-color: #eee;
|
|
|
- vertical-align: top;
|
|
|
- }
|
|
|
- &>.shop_info{
|
|
|
- vertical-align: top;
|
|
|
- display: inline-block;
|
|
|
- height: 100%;
|
|
|
- margin-left: 20upx;
|
|
|
- &>.shop_title{
|
|
|
- margin-top:0upx;
|
|
|
- font-size:40upx;
|
|
|
- font-weight: 600;
|
|
|
- color: #060606;
|
|
|
- width: 580upx;
|
|
|
- overflow: hidden;
|
|
|
- white-space: nowrap;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .fadeIn{
|
|
|
- height:180upx;
|
|
|
- overflow: hidden;
|
|
|
- animation-name: fadeInFrames;
|
|
|
- animation-duration:.3s;
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- page {
|
|
|
- background: #fff;
|
|
|
- }
|
|
|
-
|
|
|
- ::-webkit-scrollbar {
|
|
|
- width: 0;
|
|
|
- height: 0;
|
|
|
- color: transparent;
|
|
|
- }
|
|
|
-
|
|
|
- .tab-view {
|
|
|
- ::-webkit-scrollbar {
|
|
|
- width: 0;
|
|
|
- height: 0;
|
|
|
- color: transparent;
|
|
|
- }
|
|
|
- width: 200upx;
|
|
|
- position: fixed;
|
|
|
- left: 0;
|
|
|
- z-index: 10;
|
|
|
- height: calc(100vh - 160upx); /* 调整高度以适应搜索框 */
|
|
|
- background-color: #f0f2f6;
|
|
|
- .tab-bar-item {
|
|
|
- width: 200upx;
|
|
|
- height: 110upx;
|
|
|
- box-sizing: border-box;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- font-size: 28upx;
|
|
|
- color: #444;
|
|
|
- font-weight: 400;
|
|
|
- }
|
|
|
- .active {
|
|
|
- position: relative;
|
|
|
- color: $mainColor;
|
|
|
- font-size: 26upx;
|
|
|
- background: #fff;
|
|
|
- }
|
|
|
-
|
|
|
- .active::before {
|
|
|
- content: "";
|
|
|
- position: absolute;
|
|
|
- border-left: 8upx solid $mainColor;
|
|
|
- height: 100%;
|
|
|
- left: 0;
|
|
|
- }
|
|
|
- }
|
|
|
- .right-box {
|
|
|
- width: 100%;
|
|
|
- overflow: auto;
|
|
|
- height: calc(100vh - 280upx); /* 调整高度以适应搜索框 */
|
|
|
- padding-left: 220upx;
|
|
|
- box-sizing: border-box;
|
|
|
- .page-view {
|
|
|
- width: 100%;
|
|
|
- overflow: hidden;
|
|
|
- box-sizing: border-box;
|
|
|
- margin-bottom:60upx;
|
|
|
- .goods-list {
|
|
|
- @include disFlex(flex-start, flex-start);
|
|
|
- margin: 40upx 0;
|
|
|
- .img-blo {
|
|
|
- width: 200upx;
|
|
|
- height: 200upx;
|
|
|
- margin-right: 20upx;
|
|
|
- image{
|
|
|
- width: 200upx;
|
|
|
- height: 200upx;
|
|
|
- }
|
|
|
- }
|
|
|
- .goods-det {
|
|
|
- padding-top: 18upx;
|
|
|
- font-size: 28upx;
|
|
|
- position: relative;
|
|
|
- width: calc(100% - 240upx);
|
|
|
- .goods-det-top {
|
|
|
- .goods-name {
|
|
|
- font-size: 32upx;
|
|
|
- margin-bottom: 10upx;
|
|
|
- overflow: hidden;
|
|
|
- text-overflow: ellipsis;
|
|
|
- display: -webkit-box;
|
|
|
- -webkit-line-clamp: 2;
|
|
|
- line-clamp: 2;
|
|
|
- -webkit-box-orient: vertical;
|
|
|
- word-break: break-all;
|
|
|
- }
|
|
|
- }
|
|
|
- .goods-price {
|
|
|
- font-size: 22upx;
|
|
|
- margin-top: 110upx;
|
|
|
- color: #676767;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* 搜索框样式 */
|
|
|
- .search-wrap {
|
|
|
- padding: 15upx 30upx 25upx 30upx;
|
|
|
- background: linear-gradient(to bottom, #3385FF, #fff);
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 20upx;
|
|
|
- }
|
|
|
-
|
|
|
- .search-bar {
|
|
|
- flex: 1;
|
|
|
- background-color: #fff;
|
|
|
- border-radius: 30upx;
|
|
|
- padding: 2upx;
|
|
|
- box-shadow: 0upx 2px 8px 0upx rgba(0, 0, 0, 0.1);
|
|
|
- position: relative;
|
|
|
- }
|
|
|
-
|
|
|
- .search-loading {
|
|
|
- padding: 10upx 30upx;
|
|
|
- text-align: center;
|
|
|
- background-color: #f5f5f5;
|
|
|
-
|
|
|
- .loading-text {
|
|
|
- font-size: 24upx;
|
|
|
- color: #666;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .buy-material-container {
|
|
|
- flex-shrink: 0;
|
|
|
- }
|
|
|
-
|
|
|
- .buy-material-btn {
|
|
|
- position: relative;
|
|
|
- background: linear-gradient(135deg, #4caf50, #66bb6a, #81c784);
|
|
|
- border: none;
|
|
|
- border-radius: 50upx;
|
|
|
- padding: 0;
|
|
|
- height: 80upx;
|
|
|
- min-width: 160upx;
|
|
|
- box-shadow: 0 8upx 20upx rgba(76, 175, 80, 0.3);
|
|
|
- overflow: hidden;
|
|
|
-
|
|
|
-
|
|
|
- &:active {
|
|
|
- box-shadow: 0 4upx 10upx rgba(76, 175, 80, 0.4);
|
|
|
- }
|
|
|
-
|
|
|
- .btn-content {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- height: 100%;
|
|
|
- position: relative;
|
|
|
- z-index: 1;
|
|
|
- }
|
|
|
-
|
|
|
- .btn-text {
|
|
|
- color: white;
|
|
|
- font-size: 28upx;
|
|
|
- font-weight: bold;
|
|
|
- text-shadow: 0 2upx 4upx rgba(0, 0, 0, 0.2);
|
|
|
- margin: 0 8upx;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @keyframes fadeInFrames {
|
|
|
- 0% {
|
|
|
- opacity: 0;
|
|
|
- transform: translateY(0);
|
|
|
- height: 0;
|
|
|
- }
|
|
|
- 100% {
|
|
|
- opacity: 1;
|
|
|
- height: 180upx;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .buy-btn {
|
|
|
- color: red;
|
|
|
- border: 1upx solid red;
|
|
|
- border-radius: 10upx;
|
|
|
- width: 100upx;
|
|
|
- text-align: center;
|
|
|
- padding: 5upx 0;
|
|
|
- font-size: 25upx;
|
|
|
- position: absolute;
|
|
|
- right: 30upx;
|
|
|
- top: 150upx;
|
|
|
- }
|
|
|
- </style>
|
|
|
-
|