Commit b26817f8 authored by 张九刚's avatar 张九刚

feat: 新增首页和搜索相关API,更新首页和搜索页面逻辑,优化数据加载和展示

parent d4402115
import requestModule from './request.js';
const {
api
} = requestModule;
/**
* 获取首页信息
* @returns
*/
export const fetchHomeInfo = () => api.get('/c/user/index');
export const fetchHomeJSON = () => api.get('/c/front/content',{type:'home'});
\ No newline at end of file
import requestModule from './request.js';
const {
api
} = requestModule;
/**
* 获取历史搜索
* @returns
*/
export const historySearch = () => api.get('/c/mini/historySearch');
/**
* 清空历史搜索
* @returns
*/
export const historyClear = () => api.get('/c/mini/historyClear');
/**
* 搜索
*/
export const search = (data) => api.post('/c/mini/search',data);
\ No newline at end of file
This diff is collapsed.
var a ={
"swiperList": [{
"url": "homepage/banner1.jpg",
"link": {
"type": 1,
"url": "/pages/product/product?id:1-1"
}
},
{
"url": "homepage/banner2.jpg",
"link": {
"type": 2,
"url": "pages/product/product?id:1-1",
"extra": {
"appId": "wx1234567890abcdef",
"envVersion": "release"
}
}
},
{
"url": "homepage/banner3.jpg",
"link": {
"type": 3,
"url": "https://www.baidu.com",
"extra": {}
}
},
],
"vipConfigList": [
{
"grade": "-1",
"level": "注册会员",
"subTitle": "新人礼权益",
"bgUrl": "homepage/cardbg1.png",
"btnTitle": "首注200元优惠券",
"btnSubTitle": "立即注册",
},
{
"grade": "0",
"subTitle": "免费问诊权益",
"bgUrl": "homepage/cardbg1.png",
"btnTitle": "三甲医生在线问诊",
"btnSubTitle": "立即了解",
},
{
"grade": "1",
"subTitle": "育儿课程权益",
"bgUrl": "homepage/cardbg1.png",
"btnTitle": "12类系列课程",
"btnSubTitle": "立即领取",
"showCornerTxt": "待领取",
},
{
"grade": "2",
"subTitle": "育儿课程权益",
"bgUrl": "homepage/cardbg1.png",
"btnTitle": "12类系列课程",
"btnSubTitle": "立即领取",
"showCornerTxt": "待领取",
},
{
"grade": "3",
"subTitle": "月月礼权益",
"bgUrl": "homepage/cardbg1.png",
"btnTitle": "1分购、优惠券",
"btnSubTitle": "立即领取",
"showCornerTxt": "待领取",
},
{
"grade": "4",
"subTitle": "月月礼权益",
"bgUrl": "homepage/cardbg1.png",
"btnTitle": "1分购、优惠券",
"btnSubTitle": "立即领取",
"showCornerTxt": "待领取",
},
],
"vipCardList": [{
"level": "钻石会员",
"subTitle": "育儿课程权益",
"btnTitle": "12类系列课程",
"btnSubTitle": "立即领取",
"showCornerTxt": "待领取",
"link": "www.baidu.com",
"bgUrl": "homepage/cardbg1.png"
},
{
"level": "北纬47°系列",
"subTitle": "来自万年黑土的健康食品",
"btnTitle": "",
"btnSubTitle": "",
"showCornerTxt": "",
"link": "",
"bgUrl": "homepage/cardbg2.png"
},
{
"level": "育儿宝典",
"subTitle": "专家文章、育儿知识、饮食知识",
"btnTitle": "",
"btnSubTitle": "",
"showCornerTxt": "",
"link": "",
"bgUrl": "homepage/cardbg3.png"
},
],
"contentImgList": [{
"bgUrl": 'homepage/content_1.png',
"link": 'www.baidu.com',
"videoUrl": 'https://duiba.oss-cn-hangzhou.aliyuncs.com/fh/homepage/%E9%A6%96%E9%A1%B5_1%E3%80%8A%E5%AE%98%E7%BD%91%E8%A7%86%E9%A2%91%E3%80%8B_%E4%B8%8A%E7%BA%AA%E7%89%88%E5%B8%A6%E5%B0%81%E9%9D%A20306.m4v',
"_style": 'width:311rpx;height: 324rpx;left: 40rpx;top: 0;'
},
{
"bgUrl": 'homepage/content_2.png',
"link": 'www.baidu.com',
"videoUrl":"https://duiba.oss-cn-hangzhou.aliyuncs.com/fh/homepage/%E9%A6%96%E9%A1%B5_2%E9%A3%9E%E9%B9%A4%E8%BF%9E%E7%BB%AD%E4%BA%94%E5%B9%B4%E5%A5%B6%E7%B2%89%E7%AC%AC%E4%B8%80.mp4",
"_style": 'width:263rpx;height: 324rpx;right: 40rpx;top: 400rpx;'
},
{
"bgUrl": 'homepage/content_3.png',
"link": 'www.baidu.com',
"videoUrl":"https://duiba.oss-cn-hangzhou.aliyuncs.com/fh/homepage/%E9%A6%96%E9%A1%B5_3%E3%80%909%E6%9C%8827%E6%97%A5%E3%80%91%E9%A3%9E%E9%B9%A4_%E4%B8%96%E7%95%8C%E6%97%85%E6%B8%B8%E6%97%A5.mp4",
"_style": 'width:418rpx;height: 345rpx;left: 40rpx;top: 750rpx;'
},
{
"bgUrl": 'homepage/content_4.png',
"link": 'www.baidu.com',
"_style": 'width:263rpx;height: 324rpx;right: 40rpx;top: 1120rpx;'
}
],
"channelTabList": ["凯叔讲故事", "哄睡故事", "知识科普", "安全意识", "社交能力"],
"changelInfoList": [
[{
"bgUrl": "homepage/channel_0_1.png",
"title": "凯叔·金子美铃童诗:【星星和蒲公英】",
"link": "www.baidu.com"
},
{
"bgUrl": "homepage/channel_0_1.png",
"title": "凯叔·金子美铃童诗:【天空和海】",
"link": "www.baidu.com"
}
],
[{
"bgUrl": "homepage/channel_1_1.png",
"title": "凯叔-小睡仙:【睡吧睡吧,香香的】",
"link": "www.baidu.com"
},
{
"bgUrl": "homepage/channel_1_1.png",
"title": "凯叔-小睡仙:【睡觉仙气,3,2,1,】",
"link": "www.baidu.com"
}
],
[{
"bgUrl": "homepage/channel_2_1.png",
"title": "教宝宝认识人体:【守护眼睛的睫毛】",
"link": "www.baidu.com"
},
{
"bgUrl": "homepage/channel_2_1.png",
"title": "教宝宝认识人体:【为什么肚子会咕咕叫?】",
"link": "www.baidu.com"
}
],
[{
"bgUrl": "homepage/channel_3_1.png",
"title": "教宝宝不乱吃东西:【这个不能吃】",
"link": "www.baidu.com"
},
{
"bgUrl": "homepage/channel_3_1.png",
"title": "培养宝宝不摸插座的安全意识:【电线插座不好玩】",
"link": "www.baidu.com"
}
],
[{
"bgUrl": "homepage/channel_4_1.png",
"title": "教会宝宝不嘲笑别人:【鹤鸟】",
"link": "www.baidu.com"
},
{
"bgUrl": "homepage/channel_4_1.png",
"title": "培养宝宝尊重别人的习惯:【爱嘲笑人的斑斑】",
"link": "www.baidu.com"
}
]
],
"childrenInfoList": [{
"bgUrl": "homepage/children_0.png",
"title": "1+3 育儿妙招大揭秘,带娃从此不”蕉绿“",
"link": "www.baidu.com"
},
{
"bgUrl": "homepage/children_1.png",
"title": "已有儿童中招,严重可瘫痪夏季防蜱虫最全指南速看",
"link": "www.baidu.com"
},
{
"bgUrl": "homepage/children_2.png",
"title": "99% 家长忽略的脑发育关键动作",
"link": "www.baidu.com"
}
]
, "bottomLinkList": [{
"bgUrl": "homepage/iconwx.png",
"link": "www.baidu.com",
"_style": "width:70rpx;height:109rpx;"
},
{
"bgUrl": "homepage/iconqw.png",
"link": "www.baidu.com",
"_style": "width:95rpx;height:109rpx;"
},
{
"bgUrl": "homepage/iconsph.png",
"link": "www.baidu.com",
"_style": "width:70rpx;height:109rpx;"
},
{
"bgUrl": "homepage/iconxhs.png",
"link": "www.baidu.com",
"_style": "width:88rpx;height:99rpx;"
}
],
"qrInfoList": [{
"title": "公众号",
"desc": "扫码关注<span style:'color:#D3A358;'>星妈会</span>公众号,了解更多专业育儿资讯",
"qrUrl": "homepage/qrcode_gzh.png"
},
{
"title": "企业微信",
"desc": "扫码添加<span style:'color:#D3A358;'>星妈管家</span>企微,了解更多专业育儿资讯",
"qrUrl": "homepage/qrcode_qw.png"
},
{
"title": "视频号",
"desc": "扫码关注<span style:'color:#D3A358;'>星妈会</span>视频号,了解更多专业育儿资讯",
"qrUrl": "homepage/qrcode_sph.png"
},
]
}
var b = JSON.stringify(JSON.stringify(a));
console.log(b);
\ No newline at end of file
export const productsObj = {
productList: [
{
id: '1-1',
imgLength:20,
shareTitle: '产品1',
shareImg: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
},
{
id: '1-2',
imgLength:10,
shareTitle: '产品2',
shareImg: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
},
{
id: '2-1',
imgLength:15,
shareTitle: '产品1',
shareImg: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
}
]
}
\ No newline at end of file
<template>
<view class="container">
<image mode="widthFix" class="productimg" :src="$baseUrl + 'brandpage/products/' + productId + '.jpg'"></image>
<image :key="index" v-for="(item,index) in imgList" mode="widthFix" class="productimg" :src="item.imgUrl"></image>
<view class="btnbox">
<image @tap="buyHandler" class="btnbuy" :src="$baseUrl + 'brandpage/btnbuy.png'"></image>
<button class="btnshare" open-type="share" style="background: none; border: none; padding: 0;">
......@@ -11,17 +11,33 @@
</template>
<script>
import { productsObj } from '../../mock/products';
export default {
data() {
return {
productId: ''
productId: '',
imgLength:0,
imgList:[],
shareTitle:'',
shareImg:''
}
},
onLoad(options) {
// options 就是跳转时传递的参数对象
console.log('页面参数:', options);
this.productId = options.id;
const { productList } = productsObj;
const product = productList.find(item => item.id === this.productId);
this.imgLength = product.imgLength;
this.shareTitle = product.shareTitle;
this.shareImg = product.shareImg;
this.imgList = Array.from({ length: this.imgLength }, (_, index) => {
return {
imgUrl: this.$baseUrl + 'brandpage/products/' + this.productId.split('-')[0] + '/' + this.productId+'/product_'+this.productId.replace('-','_')+'_'+index + '.jpg'
}
});
},
methods: {
buyHandler() {
......@@ -43,9 +59,9 @@ export default {
},
onShareAppMessage() {
return {
title: '商品详情',
path: '/pages/product/product?id=123',
imageUrl: 'https://你的图片链接.jpg'
title: this.shareTitle,
path: '/pages/product/product?id='+this.productId,
imageUrl: this.shareImg
}
},
}
......@@ -56,6 +72,7 @@ export default {
.productimg {
width: 750rpx;
vertical-align: top;
}
.btnbox {
......
......@@ -12,8 +12,8 @@
</view>
</view>
<view class="topbox" :style="`margin-top:${statusBarHeight+10}px`">
<view v-if="step === 1" class="recentbox">
<image class="icon_trash" :src="$baseUrl+'searchpage/icon_trash.png'"></image>
<view v-if="step === 1 && recentTagsList.length > 0" class="recentbox">
<image @tap="historyClearHandler" class="icon_trash" :src="$baseUrl+'searchpage/icon_trash.png'"></image>
<view class="title">最近搜索</view>
<view class="tagbox">
<view @tap="searchHandler(item)" :key="index" v-for="(item,index) in recentTagsList" class="tag">{{item}}</view>
......@@ -53,12 +53,11 @@
<script>
import { historySearch,historyClear,search } from '../../api/search';
const recentTagsList=[
"功能营养","母婴","功能营养","母婴","功能营养","母婴","功能营养","母婴","功能营养","母婴"
]
const oftenTagsList=[
"功能营养","母婴","功能营养","母婴","功能营养","母婴","功能营养","母婴","功能营养","母婴"
]
const oftenTagsList=["婴幼儿奶粉","权益","奶酪棒","星飞帆经典"]
const resultList = [
[
{
......@@ -192,8 +191,21 @@
mounted() {
const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
this.statusBarHeight = menuButtonInfo.top;
this.initHistorySearch();
},
methods: {
initHistorySearch(){
historySearch().then(res=>{
console.log(res);
this.recentTagsList=res.data || [];
});
},
historyClearHandler(){
historyClear().then(res=>{
console.log(res);
this.recentTagsList=[]
});
},
backHandler() {
uni.navigateBack();
},
......@@ -209,6 +221,12 @@
this.searchValue=_searchValue;
}
this.step=2;
search({
keyword:this.searchValue
}).then(res=>{
console.log(res);
this.resultList=res.data || [];
});
}
}
}
......
import {
defineStore
} from 'pinia';
import {
fetchHomeInfo
} from '../api/home.js';
export const useHomeStore = defineStore('homeInfo', {
state: () => {
return {
homeInfo: null
};
},
actions: {
/**
* 更新首页信息
* @param {Object} homeInfo
*/
setHomeInfo(homeInfo) {
this.homeInfo = homeInfo;
},
/**
* 获取首页信息
*/
async loadHomeInfo() {
const {
data
} = await fetchHomeInfo();
console.log('loadHomeInfo', data);
if(data){
this.setHomeInfo(data);
}
},
},
});
\ No newline at end of file
<template>
<view class="home-container">
<view class="content">
<view class="content">
<swiper class="swiper banner" circular :indicator-dots="indicatorDots" :autoplay="autoplay"
:interval="interval" :duration="duration" :indicator-color="indicatorColor"
:indicator-active-color="indicatoractiveColor">
<swiper-item v-for="item in swiperList" :key="item.url">
<view class="swiper-item banneritem">
<image :data-link="item.link" @tap="jumpLink(item.link)" class="b-img" :src="$baseUrl + item.url">
<image :data-link="item.link" @tap="jumpBannerHandler(item)" class="b-img"
:src="$baseUrl + item.url">
</image>
</view>
</swiper-item>
......@@ -25,15 +26,15 @@
<view class="cardbox">
<view class="cardboxitem" v-for="cardData in vipCardList" :key="cardData.level">
<image class="bg" :src="$baseUrl + cardData.bgUrl"></image>
<text class="level">{{ cardData.level }}</text>
<text class="level" >{{ cardData.level }}</text>
<text class="subTitle">{{ cardData.subTitle }}</text>
<view class="showCornerTxt" v-if="cardData.showCornerTxt && cardData.showCornerTxt.length > 0">
{{ cardData.showCornerTxt }}
</view>
<view v-if="cardData.btnTitle && cardData.btnTitle.length > 0" class="cardbtn"
:data-link="cardData.link" @tap="jumpLink(cardData.link)">
:data-link="cardData.link" @tap="jumpLinkWithLogin(cardData.link)">
<image class="cardbtnbg" :src="$baseUrl + 'homepage/btn_receive.png'"></image>
<text class="btnTitle">{{ cardData.btnTitle }}</text>
<text class="btnTitle" :style="cardData.btnTitle.length>7?'font-size:22rpx;':''">{{ cardData.btnTitle }}</text>
<text class="btnSubTitle">{{ cardData.btnSubTitle }}</text>
</view>
</view>
......@@ -43,7 +44,7 @@
<image class="contentbg" :src="$baseUrl + 'homepage/contentbg.png'" alt="" />
<image class="contentitem" :key="index" :style="contentItem._style"
v-for="(contentItem, index) in contentImgList" :src="$baseUrl + contentItem.bgUrl"
@tap="jumpLink(contentItem.link)"></image>
@tap="jumpLink(contentItem.link,contentItem.videoUrl)"></image>
</view>
<view class="channelbox">
<text class="maintitle">有声频道</text>
......@@ -92,8 +93,8 @@
<view class="bottomlink">
<image class="bottombg" :src="$baseUrl + 'homepage/bottombg.png'"></image>
<view class="box">
<image class="icon" v-for="(icon, index) in bottomLinkList" :key="index" :src="$baseUrl + icon.bgUrl"
:style="icon._style" @tap="showPopup(index)"></image>
<image class="icon" v-for="(icon, index) in bottomLinkList" :key="index"
:src="$baseUrl + icon.bgUrl" :style="icon._style" @tap="showPopup(index)"></image>
</view>
</view>
</view>
......@@ -119,21 +120,30 @@
</view>
</uni-popup>
</view>
<view v-if="showVideo" class="video-popup">
<video
:src="currentVideoUrl"
controls
autoplay
style="width: 100vw; height: 56vw;"
></video>
<view class="close-btn-bottom" @tap="closeVideo">×</view>
</view>
</view>
</template>
<script>
import { jump,JumpType } from '../utils';
import { jump, JumpType } from '../utils';
import { homeObj } from '../mock/home';
import { useHomeStore } from '../stores/home';
import { fetchHomeJSON } from '../api/home';
const homeStore = useHomeStore();
export default {
data() {
return {
loading: true,
popType: 'bottom',
statusBarHeight: 38,
......@@ -144,7 +154,7 @@ export default {
duration: 500,
indicatoractiveColor: "#a6a0a1",
indicatorColor: "rgba(255, 255, 255, 1)",
vipCardList:[],
vipCardList: [],
contentImgList: [],
channelTabList: [],
channelTabIndex: 0,
......@@ -153,26 +163,56 @@ export default {
bottomLinkList: [],
qrInfoObj: undefined,
popupIndex: 0,
qrInfoList: [{ title: '', desc: '', qrUrl: '' }],
qrInfoList: [{ title: '', desc: '', qrUrl: '' }],
showVideo: false,
currentVideoUrl: '',
isLogin:false
}
},
mounted() {
const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
this.statusBarHeight = menuButtonInfo.top;
this.swiperList = homeObj.swiperList;
this.vipCardList = homeObj.vipCardList;
this.contentImgList = homeObj.contentImgList;
this.channelTabList = homeObj.channelTabList;
this.changelInfoList = homeObj.changelInfoList;
this.childrenInfoList = homeObj.childrenInfoList;
this.bottomLinkList = homeObj.bottomLinkList;
this.qrInfoList = homeObj.qrInfoList;
this.loading = false;
console.log(homeObj);
this.initHomeInfo();
},
methods: {
async initHomeInfo() {
await homeStore.loadHomeInfo();
if(homeStore.homeInfo?.memberId === "not_login"){
this.isLogin = false;
}else{
this.isLogin = true;
}
const {data} = await fetchHomeJSON();
if(data){
this.swiperList = data.swiperList;
this.vipConfigList = data.vipConfigList;
// this.vipCardList = data.vipCardList;
this.contentImgList = data.contentImgList;
this.channelTabList = data.channelTabList;
this.changelInfoList = data.changelInfoList;
this.childrenInfoList = data.childrenInfoList;
this.bottomLinkList = data.bottomLinkList;
this.qrInfoList = data.qrInfoList;
this.vipCardList = data.vipCardList;
if(this.isLogin){
this.vipCardList[0] = data.vipConfigList.find(item => item.grade === homeStore.homeInfo?.grade);
this.vipCardList[0].level = homeStore.homeInfo?.gradeName;
}else{
this.vipCardList[0] = data.vipConfigList[0];
}
}
},
changeIndicatorDots(e) {
this.indicatorDots = !this.indicatorDots
},
......@@ -185,9 +225,36 @@ export default {
durationChange(e) {
this.duration = e.target.value
},
jumpLink(_link) {
console.log(_link);
jump(_link);
jumpBannerHandler(item) {
if (item.link) {
// 有 link,执行跳转
jump(item.link);
} else {
// 没有 link,预览图片
uni.previewImage({
urls: [this.$baseUrl + item.url], // 预览当前图片
current: this.$baseUrl + item.url // 当前显示的图片
});
}
},
jumpLinkWithLogin(link){
if(this.isLogin){
jump(link);
}else{
}
},
jumpLink(link, videoUrl) {
if (videoUrl) {
// 弹出视频
this.currentVideoUrl = videoUrl;
this.showVideo = true;
return;
// 视频弹窗出现后,video标签的autoplay会自动播放
} else if (link) {
// 其他跳转逻辑
jump(link);
}
},
channelTabHandler(_index) {
this.channelTabIndex = _index;
......@@ -239,6 +306,10 @@ export default {
});
}
});
},
closeVideo() {
this.showVideo = false;
this.currentVideoUrl = '';
}
}
}
......@@ -614,5 +685,32 @@ export default {
left: 232rpx;
}
}
.video-popup {
position: fixed;
left: 0; top: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.7);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 9999;
}
.close-btn-bottom {
margin: 32rpx auto 0 auto;
width: 64rpx;
height: 64rpx;
border-radius: 50%;
background: rgba(0,0,0,0.5);
color: #fff;
font-size: 44rpx;
line-height: 64rpx;
text-align: center;
z-index: 10001;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment