feat(ID1000926):新增测评视频

This commit is contained in:
Haiyi 2023-03-09 20:11:35 +08:00
parent fdbe02791a
commit 254f060671
10 changed files with 513 additions and 107 deletions

View File

@ -1,56 +1,56 @@
{
"miniprogramRoot": "dist/",
"projectname": "EShop",
"description": "项目配置文件详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"appid": "wx714eaf2dfdb9c6bb",
"setting": {
"urlCheck": false,
"es6": false,
"enhance": true,
"postcss": false,
"preloadBackgroundData": false,
"minified": false,
"newFeature": false,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": true,
"lazyloadPlaceholderEnable": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"useApiHostProcess": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"useIsolateContext": true,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true,
"disableUseStrict": false,
"minifyWXML": true,
"showES6CompileOption": false,
"useCompilerPlugins": false,
"ignoreUploadUnusedFiles": true
"miniprogramRoot": "dist/",
"projectname": "EShop",
"description": "项目配置文件详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"appid": "wx714eaf2dfdb9c6bb",
"setting": {
"urlCheck": false,
"es6": false,
"enhance": true,
"postcss": false,
"preloadBackgroundData": false,
"minified": false,
"newFeature": false,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": true,
"lazyloadPlaceholderEnable": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"useApiHostProcess": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"compileType": "miniprogram",
"libVersion": "2.30.1",
"srcMiniprogramRoot": "dist/",
"packOptions": {
"ignore": [],
"include": []
},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
},
"condition": {}
"useIsolateContext": true,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true,
"disableUseStrict": false,
"minifyWXML": true,
"showES6CompileOption": false,
"useCompilerPlugins": false,
"ignoreUploadUnusedFiles": true
},
"compileType": "miniprogram",
"libVersion": "2.30.1",
"srcMiniprogramRoot": "dist/",
"packOptions": {
"ignore": [],
"include": []
},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
},
"condition": {}
}

View File

@ -1,52 +1,43 @@
{
"projectname": "EShop",
"setting": {
"compileHotReLoad": true,
"bigPackageSizeSupport": true,
"urlCheck": false
},
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"condition": {
"plugin": {
"list": []
"projectname": "EShop",
"setting": {
"compileHotReLoad": true,
"bigPackageSizeSupport": true,
"urlCheck": false
},
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"condition": {
"miniprogram": {
"list": [
{
"name": "收藏夹",
"pathName": "pages/collection/collectionDetail/index",
"query": "",
"launchMode": "default",
"scene": null
},
"game": {
"list": []
{
"name": "",
"pathName": "pages/sampleComparison/index",
"query": "",
"launchMode": "default",
"scene": null
},
"gamePlugin": {
"list": []
{
"name": "",
"pathName": "pages/searchList/hightSearchList",
"query": "",
"launchMode": "default",
"scene": null
},
"miniprogram": {
"list": [
{
"name": "收藏夹",
"pathName": "pages/collection/collectionDetail/index",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "",
"pathName": "pages/sampleComparison/index",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "",
"pathName": "pages/searchList/hightSearchList",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "",
"pathName": "pages/cutSampleList/index",
"query": "",
"scene": null,
"launchMode": "default"
}
]
{
"name": "",
"pathName": "pages/cutSampleList/index",
"query": "",
"launchMode": "default",
"scene": null
}
]
}
}
}

View File

@ -83,3 +83,25 @@ export const mallsearchHistorydelete = () => {
method: 'delete',
})
}
/**
*
* @returns
*/
export const MallCherryestimate_catevideolist = () => {
return useRequest({
url: '/v3/mallCherry/estimate_cate/video/list',
method: 'get',
})
}
/**
*
* @returns
*/
export const MallCherryestimate_catevideoview = () => {
return useRequest({
url: '/v3/mallCherry/estimate_cate/video/view',
method: 'get',
})
}

View File

@ -1,11 +1,11 @@
// export const BASE_URL = CURRENT_BASE_URL
export const BASE_URL = CURRENT_BASE_URL
// export const BASE_URL = `http://192.168.0.75:50001/lymarket`
// export const BASE_URL = `http://192.168.0.89:50001/lymarket`
// export const BASE_URL = `http://10.0.0.5:50001/lymarket`
// export const BASE_URL = `http://192.168.0.89:40001/lymarket`
// export const BASE_URL = `http://192.168.1.165:40001/lymarket` // 王霞
// export const BASE_URL = 'https://test.zzfzyc.com/lymarket' // 测试环境
export const BASE_URL = 'https://pre.zzfzyc.com/lymarket' // 预发布
// export const BASE_URL = 'https://pre.zzfzyc.com/lymarket' // 预发布
// export const BASE_URL = `http://192.168.1.9:40001/lymarket` // 发
// export const BASE_URL = `http://192.168.1.9:50005/lymarket` // 发
// export const BASE_URL = `http://192.168.1.30:50001/lymarket` // 发
@ -13,7 +13,7 @@ export const BASE_URL = 'https://pre.zzfzyc.com/lymarket' // 预发布
// export const BASE_URL = 'https://www.zzfzyc.com/lymarket' // 正式环境
// export const BASE_URL = `http://192.168.1.5:40001/lymarket` // 王霞
// export const BASE_URL = 'http://192.168.1.7:50002/lymarket' // 添
// export const BASE_URL = 'http://192.168.1.28:50001/lymarket' // 婷
// export const BASE_URL = 'http://192.168.1.28:50002/lymarket' // 婷
// export const BASE_URL = 'http://192.168.1.42:50002/lymarket' // 杰
// CDN

View File

@ -56,3 +56,44 @@
width: 130px;
height: 130px;
}
.no_bg_moveBtn_next {
box-shadow: none;
background-color: transparent;
border: none;
width: 200px;
height: 130px;
}
.no_bg_moveBtn_next_ever {
display: none;
}
.video_box {
border-radius: 16px;
width: 300px;
height: 300px;
// background-color: red;
position: relative;
.clearBtn {
z-index: 9999;
position: absolute;
top: 20px;
right: 10px;
}
.bottom_box {
width: 100%;
position: absolute;
bottom: -100px;
z-index: 999;
text-align: center;
width: 100%;
height: 40px;
line-height: 40px;
background-color: #337fff;
color: #fff;
border-bottom-left-radius: 16px;
border-bottom-right-radius: 16px;
font-size: 26px;
}
}

View File

@ -1,4 +1,4 @@
import { Button, Image, MovableArea, MovableView, View } from '@tarojs/components'
import { Button, CoverView, Image, MovableArea, MovableView, Video, View } from '@tarojs/components'
import Taro, { useDidShow, useReady, useRouter } from '@tarojs/taro'
import type { ReactElement } from 'react'
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
@ -12,6 +12,8 @@ import { useSelector } from '@/reducers/hooks'
import { alert } from '@/common/common'
import { formatImgUrl } from '@/common/fotmat'
import { ORDER_STATUS } from '@/common/enum'
import IconFont from '@/components/iconfont/iconfont'
import { IMG_CND_Prefix } from '@/common/constant'
type ShowStatus = 'shop'|'customer'|'order'|'code'
interface param {
@ -22,8 +24,11 @@ interface param {
messagePath?: string
showCart?: false|true
orderObj?: any
playVideo?: boolean
floatVideoFile?: any[]
showFloatVideo?: boolean
}
const MoveBtn = ({ orderObj = {}, children = null, onShopClick, showList = [], messageTitle = '', messagePath = '', showCart = false }: param) => {
const MoveBtn = ({ showFloatVideo = false, floatVideoFile = [], playVideo = true, orderObj = {}, children = null, onShopClick, showList = [], messageTitle = '', messagePath = '', showCart = false }: param) => {
const userInfo = useSelector(state => state.userInfo)
// 获取购物车数据数量
const { getShopCount, commonData } = useCommonData()
@ -94,6 +99,21 @@ const MoveBtn = ({ orderObj = {}, children = null, onShopClick, showList = [], m
].includes(orderObj.status)
}, [orderObj.status])
const [showVido, setshowVido] = useState(true)
const handShowVideo = () => {
const videoplay = Taro.createVideoContext('video')
videoplay.pause()
setshowVido(false)
}
useEffect(() => {
if (!playVideo) {
const videoplay = Taro.createVideoContext('video')
videoplay.pause()
}
}, [playVideo])
return (
<MovableArea className={styles.movableItem}>
{children}
@ -128,6 +148,29 @@ const MoveBtn = ({ orderObj = {}, children = null, onShopClick, showList = [], m
>
<Image mode="aspectFit" src={formatImgUrl('/mall/float_button_customer_service.png')} />
</MovableView>}
{onShow('order') && <MovableView
className={classnames(styles.moveBtn, showVido && showFloatVideo ? styles.no_bg_moveBtn_next : styles.no_bg_moveBtn_next_ever)}
direction="all"
inertia
x="470rpx"
y="100rpx"
>
<View className={styles.video_box}>
<View className={styles.clearBtn} onClick={() => handShowVideo()}>
<IconFont name="icon-qingchuxinxi" size={60} color="#acacac"></IconFont>
</View>
<Video
style={{ width: '300rpx', height: '400rpx', borderRadius: '32rpx' }}
autoplay
id="video"
src={floatVideoFile.length ? IMG_CND_Prefix + floatVideoFile[0].video_url[0] : ''}
loop
object-fit="contain"
></Video>
<View className={styles.bottom_box}>{floatVideoFile?.[0]?.title}</View>
</View>
</MovableView>}
{showCode && <CodeSelect orderObj={orderObj} y={screenHeight.code as number} />}
<Customer messageTitle={messageTitle} messagePath={messageTitle} show={customer_service_show} showCard={showCart} onClose={customerClose} />
</MovableArea>

View File

@ -0,0 +1,9 @@
.scrollStyle {
white-space: nowrap;
width: 100%;
// border-radius: 16px;
// height: 450px;
// background-color: #fff;
// margin-top: 25px;
// margin-bottom: 25px;
}

View File

@ -0,0 +1,29 @@
import { Button, Icon, RichText, ScrollView, Text, View } from '@tarojs/components'
import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro'
import type { ReactNode } from 'react'
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import styles from './index.module.scss'
interface Params {
children?: ReactNode | null
onScrollToLower: () => void
}
const ScrollViewX = (Props: Params) => {
return (
<ScrollView
className={styles.scrollStyle}
scrollX
lowerThreshold={50}
onScrollToLower={Props.onScrollToLower}
enhanced
pagingEnabled
enablePassive="true"
>
{Props.children}
</ScrollView>
)
}
export default memo(ScrollViewX)

View File

@ -169,6 +169,145 @@ page {
}
}
}
.ccum_box {
border-radius: 16px;
width: 100%;
// display: flex;
height: 450px;
overflow: hidden;
overflow-x: auto;
white-space: nowrap;
background-color: #fff;
// flex-shrink: 0;
margin-top: 25px;
margin-bottom: 25xp;
}
.scroll_box {
padding-top: 30px;
width: 100%;
border-radius: 16px;
height: 450px;
background-color: #fff;
margin-top: 25px;
margin-bottom: 25px;
.title {
margin-left: 25px;
color: rgba(0, 0, 0, 0.8);
font-weight: 500;
font-size: 28px;
margin-bottom: 20px;
}
}
.item_box {
display: inline-block;
// margin-left: 40px;
// margin-top: 30px;
margin: 20px;
width: 300px;
height: 190px;
position: relative;
.cricle {
position: absolute;
top: 20px;
right: 20px;
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #c7c7c7;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
z-index: 45;
.icon {
margin-left: 20px;
width: 0px;
height: 0px;
border: 15px solid transparent; /*以下四个样式对应四种三角形,任选其一即可实现*/
/* border-top-color:lightseagreen; */
border-left-color: #fff;
// border-right-color: lightseagreen;
// border-bottom-color: lightseagreen;
}
}
.img_style {
border-top-right-radius: 16px;
border-top-left-radius: 16px;
// top: 0;
// left: 0;
position: absolute;
z-index: 12;
width: 300px;
height: 242px;
}
.bottom_box {
position: absolute;
bottom: -102px;
z-index: 50;
text-align: center;
width: 100%;
height: 50px;
line-height: 50px;
background-color: #c9c9c9;
color: #fff;
border-bottom-left-radius: 16px;
border-bottom-right-radius: 16px;
font-size: 26px;
}
.title_name {
text-align: center;
font-size: 28px;
margin-top: 10px;
}
}
.tag_box {
padding-top: 30px;
// padding-bottom: 30px;
width: 100%;
border-radius: 16px;
background-color: #fff;
margin-top: 25px;
margin-bottom: 25px;
.title {
margin-left: 25px;
color: rgba(0, 0, 0, 0.8);
font-weight: 500;
font-size: 28px;
margin-bottom: 20px;
}
.tag_big {
// display: flex;
// flex-wrap: wrap;
display: grid;
grid-template-columns: 25% 25% 25% 25%;
justify-content: space-between;
.tag_item {
box-sizing: border-box;
// margin-left: 30px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-bottom: 28px;
// flex: 1;
.tag_img {
width: 90px;
height: 90px;
border-radius: 50%;
margin-bottom: 15px;
}
.tag_title {
text-align: center;
font-size: 28px;
margin-top: 10px;
}
}
}
}
.product_detail {
// padding: 20px;
background-color: #fff;
@ -187,6 +326,7 @@ page {
background-color: #fff;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
z-index: 9999;
.icon_btn {
display: flex;
flex: 1;

View File

@ -1,4 +1,4 @@
import { Button, Icon, RichText, Text, View } from '@tarojs/components'
import { Button, CoverView, Icon, Image, RichText, Text, Video, View } from '@tarojs/components'
import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro'
import classnames from 'classnames'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
@ -7,9 +7,10 @@ import OrderCount from './components/orderCount'
import styles from './index.module.scss'
import FeaturePopup from './components/feature'
import Recommend from './components/recommend'
import ScrollViewX from './components/scrollViewX'
import ShopCart from '@/components/shopCart'
import { formatDateTime, formatHashTag, formatImgUrl, formatPriceDiv, formatRemoveHashTag } from '@/common/fotmat'
import { GetProductDetailApi } from '@/api/material'
import { GetProductDetailApi, MallCherryestimate_catevideolist, MallCherryestimate_catevideoview } from '@/api/material'
import useLogin from '@/use/useLogin'
import { AnalysisShortCodeApi, GetShortCodeApi } from '@/api/share'
import { SHARE_SCENE } from '@/common/enum'
@ -26,6 +27,7 @@ import IconFont from '@/components/iconfont/iconfont'
import LabAndImgShow from '@/components/LabAndImgShow'
import PopupSelectColor from '@/components/popupSelectColor'
import { GetColorCardOrderByProductApi } from '@/api/colorCard'
import { IMG_CND_Prefix } from '@/common/constant'
interface item { title: string; img: string; url: string; id: number }
@ -274,8 +276,81 @@ const Details = (props: Params) => {
})
}
// 获取性能测评视频
const [videoList, setvideoList] = useState<any[]>([])
// 浮窗视频url
const [floatUrl, setfloatUrl] = useState<any[]>([])
useEffect(() => {
getVideoList()
}, [])
const { fetchData: viewFetch } = MallCherryestimate_catevideolist()
const getVideoList = async() => {
console.log(router.params.id, '4545646')
const res = await viewFetch({ ...videoCurrent.current })
if (videoCurrent.current.page == 1 && res.data.list.length) {
// setfloatUrl(IMG_CND_Prefix + res.data.list?.[0].video_url[0] || '')
setfloatUrl([res.data.list[0]] || [])
setshowFloatVideo(true)
}
if (!res.data.list.length) {
setfloatUrl([])
setshowVideoPlay(false)
setshowFloatVideo(false)
}
if (res.data.list.length) {
// setvideoList(val => ({ ...val, ...res.data.list }))
setvideoList([...videoList, ...res.data.list])
console.log(videoList, '456456')
}
videoCurrent.current.total = res.data.total
}
const videoCurrent = useRef({
page: 1,
size: 10,
product_id: Number(router.params.id),
total: 0,
status: 0,
})
// 分页控制
const handOnScrollToLower = () => {
if (videoCurrent.current.page * videoCurrent.current.size >= videoCurrent.current.total) { return }
videoCurrent.current.page += 1
getVideoList()
console.log(111, videoCurrent.current.page)
}
// 视频播放
const { fetchData: viewNumsFetch } = MallCherryestimate_catevideoview()
const handPlay = async(id, elementId) => {
await viewNumsFetch({ id })
setshowVideoPlay(false)
const videoplay = Taro.createVideoContext(elementId)
videoplay.requestFullScreen({ direction: 0 })
videoplay.play()
}
const handleClose = (event, elementId) => {
if (!event.detail.fullScreen) {
const videoplay = Taro.createVideoContext(elementId)
videoplay.pause()
}
}
// 控制浮窗的视频是否被其他的视频影响
const [showVideoPlay, setshowVideoPlay] = useState(true)
const [showFloatVideo, setshowFloatVideo] = useState(false)
return (
<MoveBtn showList={['order']}>
<MoveBtn showList={['order']} playVideo={showVideoPlay} floatVideoFile={floatUrl} showFloatVideo={showFloatVideo}>
<View className={styles.main}>
<View className={styles.content}>
<DesSwiper list={productInfo.texture_url ? productInfo.texture_url.toString().split(',') : []} />
@ -360,6 +435,62 @@ const Details = (props: Params) => {
})}
</View>
</View>
{
videoList.length > 0 && <View className={styles.scroll_box}>
<View className={styles.title}></View>
<ScrollViewX
onScrollToLower={() => handOnScrollToLower()}
>
{
videoList.map((item, index) => {
return (
<View className={styles.item_box} key={index}>
<View className={styles.cricle} onClick={() => handPlay(item.estimate_video_id, `video${index}`)}>
<View className={styles.icon}></View>
</View>
<Image
className={styles.img_style}
src={item.video_pic.length ? IMG_CND_Prefix + item.video_pic[0] : IMG_CND_Prefix + item.frame_pic}
mode="aspectFill"
></Image>
<Video
style={{ width: '300rpx', height: '290rpx', borderRadius: '16rpx' }}
id={`video${index}`}
src={IMG_CND_Prefix + item.video_url[0]}
object-fit="contain"
show-center-play-btn={false}
show-play-btn={false}
show-fullscreen-btn={false}
onFullScreenChange={event => handleClose(event, `video${index}`)}
></Video>
<View className={styles.bottom_box}>{item.result}</View>
<View className={styles.title_name}>{item.title}</View>
</View>
)
})
}
</ScrollViewX>
</View>
}
{
(productInfo?.clothes_is_consult && productInfo?.clothes_is_consult?.length > 0)
&& <View className={styles.tag_box}>
<View className={styles.title}></View>
<View className={styles.tag_big}>
{
productInfo?.clothes_is_consult.map((item, index) => {
return (
<View className={styles.tag_item} key={index}>
<Image className={styles.tag_img} mode="aspectFill" src={IMG_CND_Prefix + item?.icon[0]}></Image>
<View className={styles.tag_title}>{item?.product_label_name}</View>
</View>
)
})
}
</View>
</View>
}
<View className={styles.product_detail}>
<RichText nodes={html}></RichText>
</View>