Просмотр исходного кода

Merge branch 'master' into dev

shish 1 год назад
Родитель
Сommit
1fa91dd737

+ 1 - 1
hdApp/src/admin/goods/price-increase.vue

@@ -42,7 +42,7 @@
 					</tui-list-cell>
 				</block>
 			</div>
-			<div class="prompt-text">涨价只对花束商城生效,花材和花束图集无效</div>
+			<div class="prompt-text">涨价只对花束商城生效,花材和花束相册无效</div>
 		</block>
 		<div class="button-group">
 			<button class="admin-button-com default big cancel-btn" @click="goBack">取消</button>

+ 4 - 4
hdApp/src/admin/home/workbench.vue

@@ -83,7 +83,7 @@
               <view class="icon-wrapper">
                 <image class="icon-image" :src="`${constant.hostUrl}/image/ghs/home/shop2.png`" mode="aspectFit"></image>
               </view>
-              <view class="icon-text">图集</view>
+              <view class="icon-text">相册</view>
             </view>
             <view class="icon-item" @click="goHsKd">
               <view class="icon-wrapper">
@@ -870,7 +870,7 @@ export default {
       if(this.urlNo == 1){
         url = 'pages/home/category'
       }
-      //图集
+      //相册
       if(this.urlNo == 2){
         url = 'pages/home/mall'
       }
@@ -890,10 +890,10 @@ export default {
         currentShortUrl = this.shortUrlList['goodsUrl']
         text = "点击下面链接,打开商城\n\n"+currentShortUrl
       }
-      //图集
+      //相册
       if(this.urlNo == 2){
         currentShortUrl = this.shortUrlList['imgUrl']
-        text = "点击下面链接,打开图集\n\n"+currentShortUrl
+        text = "点击下面链接,打开相册\n\n"+currentShortUrl
       }
       //绿植花材商城
       if(this.urlNo == 3){

+ 4 - 0
hdPad/src/api/goods/index.js

@@ -149,3 +149,7 @@ export const getRise = data => {
 export const updateRise = data => {
 	return https.post('/goods/update-rise', data)
 }
+
+export const getCategoryToGoods = data => {
+	return https.get('/category/goods-list', data)
+}

+ 2 - 2
hdPad/src/pages/home/components/rightGoods.vue

@@ -39,7 +39,7 @@
     </view>
 </template>
 <script>
-import { getGoodsInfoList } from '@/api/goods'
+import { getCategoryToGoods } from '@/api/goods'
 import { getAllClass } from '@/api/category'
 import productMins from "@/mixins/product";
 import list from "@/mixins/list";
@@ -136,7 +136,7 @@ export default {
             })
         },
         getShowData(){
-            getGoodsInfoList({page:this.list.page,pageSize:30,cId:this.selIndex,flowerNum:this.flowerNum}).then(res=>{
+            getCategoryToGoods({page:this.list.page,pageSize:30,cId:this.selIndex,flowerNum:this.flowerNum,requestType:'kd'}).then(res=>{
                 if(res.code == 1){
                     this.completes(res)
                 }

+ 1 - 1
mallApp/src/pages.json

@@ -2,7 +2,7 @@
     "pages": [{ "path": "pages/home/recent", "style": { "navigationBarTitleText": "我的花店","enablePullDownRefresh":true} },
         { "path": "pages/home/index", "style": { "navigationBarTitleText": "首页" } },
         { "path": "pages/home/category", "style": { "navigationBarTitleText": "花束花礼" } },
-        { "path": "pages/home/mall", "style": { "navigationBarTitleText": "图集" } },
+        { "path": "pages/home/mall", "style": { "navigationBarTitleText": "相册" } },
         { "path": "pages/home/shop", "style": { "navigationBarTitleText": "门店" } },
         { "path": "pages/home/user", "style": { "navigationBarTitleText": "我的" } },
         { "path": "pages/home/course", "style": { "navigationBarTitleText": "课程"}},

+ 105 - 6
mallApp/src/pages/home/category.vue

@@ -10,7 +10,7 @@
 			</view>
 		</view>
 
-		<!-- 搜索框和花材绿植按钮区域 -->
+		<!-- 搜索框和按钮区域 -->
 		<view class="search-wrap">
 			<view class="search-bar">
 				<app-search-module 
@@ -21,7 +21,13 @@
 					:fontSize="28"
 				/>
 			</view>
-			<view class="buy-material-container">
+			<view class="buy-flower-container">
+				<button class="buy-flower-btn" @click="buyAlbum()">
+					<view class="btn-content">
+						<view class="flower-icon-css"></view>
+						<text class="btn-text">花束相册</text>
+					</view>
+				</button>
 				<button class="buy-material-btn" @click="buyProduct()">
 					<view class="btn-content">
 						<text class="btn-text">花材绿植</text>
@@ -177,6 +183,10 @@ export default {
       let account = this.option.account?this.option.account:0
       this.$util.pageTo({url:"/pages/item/item?account="+account+'&hdId='+this.hdId,type:2})
     },
+    buyAlbum(){
+      let account = this.option.account ? this.option.account : 0
+      this.$util.pageTo({url: "/pages/home/mall?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})
@@ -267,7 +277,8 @@ export default {
         searchText: this.searchText, 
         page: this.list.page, 
         pageSize: 10,
-        hdId:hdId
+        hdId:hdId,
+        requestType:'album'
       }).then(res => {
         this.completes(res)
       }).catch(err => {
@@ -275,7 +286,6 @@ export default {
       })
     },
     reachBottom () {
-      console.log('reachBottom----------', this.list.finished)
       if (this.list.finished == false) {
         // 根据是否为搜索模式决定调用哪个方法
         if (this.isSearchMode) {
@@ -307,7 +317,7 @@ export default {
     },
     // 列表
     getGoodList () {
-      return getList({ ...this.form, page: this.list.page,pageSize:10 }) .then(res => {
+      return getList({...this.form, page: this.list.page,pageSize:10,requestType:'album'}) .then(res => {
           // 处理商品列表数据,completes方法来自list混入
           // 该方法会处理分页数据,更新list对象的data、page、finished等属性
           // res包含接口返回的商品列表数据,completes方法会将数据添加到this.list.data中
@@ -564,8 +574,85 @@ page {
 	}
 }
 
-.buy-material-container {
+.buy-flower-container {
 	flex-shrink: 0;
+	display: flex;
+	gap: 10upx;
+}
+
+.buy-flower-btn {
+	position: relative;
+	background: linear-gradient(135deg, #ff6b6b, #ff8e8e, #ffa8a8);
+	border: none;
+	border-radius: 50upx;
+	padding: 0;
+	height: 80upx;
+	min-width: 200upx;
+	box-shadow: 0 8upx 20upx rgba(255, 107, 107, 0.3);
+	overflow: hidden;
+	animation: pulse 2s infinite;
+
+	&:active {
+		box-shadow: 0 4upx 10upx rgba(255, 107, 107, 0.4);
+	}
+
+	.btn-content {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		height: 100%;
+		position: relative;
+		z-index: 1;
+		text-align: center;
+	}
+
+	.flower-icon-css {
+		width: 24upx;
+		height: 24upx;
+		margin-right: 8upx;
+		position: relative;
+
+		&::before {
+			content: '';
+			position: absolute;
+			width: 16upx;
+			height: 16upx;
+			background: #fff;
+			border-radius: 50%;
+			top: 4upx;
+			left: 4upx;
+			box-shadow: 
+				0 -8upx 0 -2upx #fff,
+				8upx -6upx 0 -2upx #fff,
+				8upx 6upx 0 -2upx #fff,
+				0 8upx 0 -2upx #fff,
+				-8upx 6upx 0 -2upx #fff,
+				-8upx -6upx 0 -2upx #fff;
+		}
+
+		&::after {
+			content: '';
+			position: absolute;
+			width: 8upx;
+			height: 8upx;
+			background: #ffeb3b;
+			border-radius: 50%;
+			top: 8upx;
+			left: 8upx;
+		}
+	}
+
+	.btn-text {
+		color: white;
+		font-size: 28upx;
+		font-weight: bold;
+		text-shadow: 0 2upx 4upx rgba(0, 0, 0, 0.2);
+		margin-right: 8upx;
+		text-align: center;
+		line-height: 1;
+		display: flex;
+		align-items: center;
+	}
 }
 
 .buy-material-btn {
@@ -602,6 +689,18 @@ page {
 	}
 }
 
+@keyframes pulse {
+	0% {
+		box-shadow: 0 8upx 20upx rgba(255, 107, 107, 0.3);
+	}
+	50% {
+		box-shadow: 0 12upx 30upx rgba(255, 107, 107, 0.4);
+	}
+	100% {
+		box-shadow: 0 8upx 20upx rgba(255, 107, 107, 0.3);
+	}
+}
+
 @keyframes fadeInFrames {
 	0% {
 		opacity: 0;

+ 712 - 3
mallApp/src/pages/home/mall.vue

@@ -1,5 +1,714 @@
 <template>
-  <view class="app_content">
-    <view></view>
+  <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="搜索商品" 
+					@input="searchFn" 
+					:height="66"
+					:fontSize="28"
+				/>
+			</view>
+			<view class="buy-flower-container">
+				<button class="buy-flower-btn" @click="buyHs()">
+					<view class="btn-content">
+						<view class="flower-icon-css"></view>
+						<text class="btn-text">花束花礼</text>
+					</view>
+				</button>
+				<button class="buy-material-btn" @click="buyProduct()">
+					<view class="btn-content">
+						<text class="btn-text">花材绿植</text>
+					</view>
+				</button>
+			</view>
+		</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">--</view>
+            <view class="buy-btn">查看</view>
+          </view>
+        </view>
+      </view>
+      <block v-else>
+        <app-wrapper-empty 
+          :title="getEmptyTitle()" 
+          :is-empty="true" 
+        />
+      </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">--</view>
+              <view class="buy-btn">查看</view>
+            </view>
+          </view>
+        </view>
+        <block v-else>
+          <app-wrapper-empty 
+            :title="getEmptyTitle()" 
+            :is-empty="true" 
+          />
+        </block>
+      </scroll-view>
+    </block>
+
+    <wangCg :loginStyle.sync="globalLoginStyle" @goToLogin="loginTo()"></wangCg>
   </view>
-</template>
+</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, getList } from '@/api/category'
+import { list,share } from '@/mixins'
+import { getInfo } from "@/api/shop"
+export default {
+  name: 'mall',
+  components: {
+    AppWrapperEmpty,
+    AppImg,
+    wangCg,
+    AppSearchModule
+  },
+  mixins: [list, share],
+  data () {
+    return {
+      tabbar: [],
+      height: 0,
+      currentTab: 0,
+      scrollTop: 0,
+      categoryId: '',
+      currentTabIndex: 1,
+      myClass: 'fadeIn',
+			shopName:'',
+			shopImg:'',
+      hdId:0,
+      searchText: '', // 搜索文本
+      searchTimer: null, // 搜索防抖定时器
+      isSearchMode: 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.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})
+    },
+    buyHs(){
+      let account = this.option.account ? this.option.account : 0
+      this.$util.pageTo({url: "/pages/home/category?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() {
+
+      // 清除之前的定时器
+      if (this.searchTimer) {
+        clearTimeout(this.searchTimer)
+        this.searchTimer = null
+      }
+      
+      // 如果搜索文本为空
+      if (this.$util.isEmpty(this.searchText)) {
+        // 如果之前也是空文本(首次点击或焦点清空),跳过搜索
+        if (this.$util.isEmpty(this.lastSearchText)) {
+          return
+        }
+        // 如果之前有搜索文本,现在清空了,则恢复分类筛选
+        this.clearSearch()
+        return
+      }
+      
+      // 如果搜索文本与上次相同,不重复搜索
+      if (this.searchText === this.lastSearchText) {
+        return
+      }
+      
+      // 设置防抖定时器,1秒后执行搜索
+      this.searchTimer = setTimeout(() => {
+        this.performSearch()
+      }, 1000)
+    },
+    
+    // 执行搜索
+    performSearch() {
+      if (this.$util.isEmpty(this.searchText)) {
+        return
+      }
+      this.isSearchMode = true
+      this.lastSearchText = this.searchText
+      this.resetList()
+      this.searchGoods()
+    },
+    
+    // 清空搜索,恢复分类筛选
+    clearSearch() {
+      this.isSearchMode = false
+      this.lastSearchText = ''
+      
+      // 确保搜索框内容被清空
+      this.$nextTick(() => {
+        this.searchText = ''
+      })
+      
+      this.resetList()
+      this.getGoodList()
+    },
+    reachBottom () {
+      if (this.list.finished == false) {
+        // 根据是否为搜索模式决定调用哪个方法
+        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.categoryId = res.data[0].id
+          this.tabbar = res.data
+        }
+      })
+    },
+    // 搜索商品
+    searchGoods() {
+      this.getGoodList()
+    },
+    // 列表
+    getGoodList () {
+      let hdId = this.option.id?this.option.id:0
+      return getList({ cId:this.categoryId, page: this.list.page,pageSize:10,requestType:'mall',searchText: this.searchText,hdId:hdId}) .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.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.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:160upx;
+    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: 32upx;
+          margin-top: 50upx;
+          color: $mainColor;
+          font-weight: bold;
+        }
+      }
+    }
+  }
+}
+
+/* 搜索框样式 */
+.search-wrap {
+	padding: 15upx 30upx 25upx 30upx;
+	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-flower-container {
+	flex-shrink: 0;
+	display: flex;
+	gap: 10upx;
+}
+
+.buy-flower-btn {
+	position: relative;
+	background: linear-gradient(135deg, #ff6b6b, #ff8e8e, #ffa8a8);
+	border: none;
+	border-radius: 50upx;
+	padding: 0;
+	height: 80upx;
+	min-width: 200upx;
+	box-shadow: 0 8upx 20upx rgba(255, 107, 107, 0.3);
+	overflow: hidden;
+	animation: pulse 2s infinite;
+
+	&:active {
+		box-shadow: 0 4upx 10upx rgba(255, 107, 107, 0.4);
+	}
+
+	.btn-content {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		height: 100%;
+		position: relative;
+		z-index: 1;
+		text-align: center;
+	}
+
+	.flower-icon-css {
+		width: 24upx;
+		height: 24upx;
+		margin-right: 8upx;
+		position: relative;
+
+		&::before {
+			content: '';
+			position: absolute;
+			width: 16upx;
+			height: 16upx;
+			background: #fff;
+			border-radius: 50%;
+			top: 4upx;
+			left: 4upx;
+			box-shadow: 
+				0 -8upx 0 -2upx #fff,
+				8upx -6upx 0 -2upx #fff,
+				8upx 6upx 0 -2upx #fff,
+				0 8upx 0 -2upx #fff,
+				-8upx 6upx 0 -2upx #fff,
+				-8upx -6upx 0 -2upx #fff;
+		}
+
+		&::after {
+			content: '';
+			position: absolute;
+			width: 8upx;
+			height: 8upx;
+			background: #ffeb3b;
+			border-radius: 50%;
+			top: 8upx;
+			left: 8upx;
+		}
+	}
+
+	.btn-text {
+		color: white;
+		font-size: 28upx;
+		font-weight: bold;
+		text-shadow: 0 2upx 4upx rgba(0, 0, 0, 0.2);
+		margin-right: 8upx;
+		text-align: center;
+		line-height: 1;
+		display: flex;
+		align-items: center;
+	}
+}
+
+.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 pulse {
+	0% {
+		box-shadow: 0 8upx 20upx rgba(255, 107, 107, 0.3);
+	}
+	50% {
+		box-shadow: 0 12upx 30upx rgba(255, 107, 107, 0.4);
+	}
+	100% {
+		box-shadow: 0 8upx 20upx rgba(255, 107, 107, 0.3);
+	}
+}
+
+@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: 80upx;
+  text-align: center;
+  padding: 5upx 0;
+  font-size: 25upx;
+  position: absolute;
+  right: 30upx;
+  top: 150upx;
+}
+</style>

+ 1 - 1
mallApp/src/pages/home/recent.vue

@@ -79,7 +79,7 @@
 
               <view class="button_9 flex-col" @click.stop="hs(item)"><text class="text_13">花束</text></view>
 
-              <view class="button_15 flex-col" @click.stop="tj(item)"><text class="text_13">图集</text></view>
+              <view class="button_15 flex-col" @click.stop="tj(item)"><text class="text_13">相册</text></view>
 
               </view>
           </view>

+ 18 - 3
mallApp/src/pages/item/item.vue

@@ -15,11 +15,16 @@
 				<app-search-module v-model="py" placeholder="这里搜索" @input="searchFn" />
 			</view>
 			<view class="buy-flower-container">
+				<button class="buy-flower-btn" @click="buyAlbum()">
+					<view class="btn-content">
+						<view class="flower-icon-css"></view>
+						<text class="btn-text">花束相册</text>
+					</view>
+				</button>
 				<button class="buy-flower-btn" @click="buyHs()">
 					<view class="btn-content">
 						<view class="flower-icon-css"></view>
 						<text class="btn-text">花束花礼</text>
-						<view class="sparkle-css"></view>
 					</view>
 				</button>
 			</view>
@@ -306,9 +311,13 @@ export default {
 		hidePopup() {
 			this.popupShow = false;
 		},
+		buyAlbum(){
+			let account = this.option.account ? this.option.account : 0
+			this.$util.pageTo({url: "/pages/home/mall?account="+account+'&hdId='+this.hdId,type:2})
+		},
 		buyHs(){
 			let account = this.option.account ? this.option.account : 0
-			this.$util.pageTo({url: "/pages/home/category?account="+account+'&hdId='+this.hdId,type:2})
+			this.$util.pageTo({url: "/pages/home/category?account="+account+'&hdId='+this.hdId,type:2})
 		},
 		showBigCover(item){
       		this.$util.pageTo({url: "/pages/item/detail?id="+item.id+"&account="+this.option.account+'&hdId='+this.hdId})
@@ -556,6 +565,8 @@ export default {
 	.buy-flower-container {
 		margin-left: 20upx;
 		padding: 0;
+		display: flex;
+		gap: 10upx;
 	}
 
 	.buy-flower-btn {
@@ -582,6 +593,7 @@ export default {
 		height: 100%;
 		position: relative;
 		z-index: 1;
+		text-align: center;
 	}
 
 	.flower-icon-css {
@@ -589,7 +601,6 @@ export default {
 		height: 24upx;
 		margin-right: 8upx;
 		position: relative;
-		animation: bounce 1.5s infinite;
 
 		&::before {
 			content: '';
@@ -627,6 +638,10 @@ export default {
 		font-weight: bold;
 		text-shadow: 0 2upx 4upx rgba(0, 0, 0, 0.2);
 		margin-right: 8upx;
+		text-align: center;
+		line-height: 1;
+		display: flex;
+		align-items: center;
 	}
 
 	.sparkle-css {