新增图片默认加载类型 和 我的页面header动画

v2
king 1 year ago
parent a43fc7498c
commit 70e61e187e
  1. 4
      .env
  2. 16
      src/api/brand.ts
  3. 29
      src/components/image/image.tsx
  4. 1
      src/components/learningRecord/learningRecord.tsx
  5. 5
      src/pages/my/components/header/header.tsx
  6. 10
      src/pages/my/my.module.scss
  7. 8
      src/pages/my/my.tsx
  8. 11
      src/pages/preview/brand/list/list.tsx

@ -1,5 +1,5 @@
#TARO_APP_API=https://yjx.dev.yaojiankang.top
TARO_APP_API=https://mooc.yaojiankang.top
TARO_APP_API=https://yjx.dev.yaojiankang.top
#TARO_APP_API=https://mooc.yaojiankang.top
#TARO_APP_API=https://shopfix.yaojiankang.top
#TARO_APP_API=https://playedu.yaojiankang.top
TARO_APP_LGOIN=true

@ -8,7 +8,9 @@ export type BrandRecord = {
brand_album: string
graphic_introduction: string
disabled: number
introductory_video_resource:any
introductory_video_resource: any
article_count: number
created_at: string
}
export type ArticleRecord = {
title: string
@ -19,24 +21,24 @@ export type ArticleRecord = {
export const brandApi = {
/** 品牌列表 */
list(page: number , page_size: number) {
list(page: number, page_size: number) {
return request<{
list: BrandRecord[],
total: number
}>(`/home/v1/brand/list?page=${page}&page_size=${page_size}` , "GET")
}>(`/home/v1/brand/list?page=${page}&page_size=${page_size}`, "GET")
},
/** 品牌详情 */
info(id: number) {
return request<BrandRecord>(`/home/v1/brand/${id}`, "GET")
},
/** 文章列表 */
articleList(owner_id: number,page:number) {
articleList(owner_id: number, page: number) {
return request<{
list: ArticleRecord[],
total: number
}>(`/home/v1/article/list?owner_id=${owner_id}&page=${page}&page_size=10` , "GET")
}>(`/home/v1/article/list?owner_id=${owner_id}&page=${page}&page_size=10`, "GET")
},
articleInfo(id: number ) {
return request<ArticleRecord>(`/home/v1/article/${id}` , "GET")
articleInfo(id: number) {
return request<ArticleRecord>(`/home/v1/article/${id}`, "GET")
},
}

@ -3,16 +3,19 @@ import {Image, ImageProps, View} from "@tarojs/components";
import shard from '@/static/img/shard.png'
import styles from './image.module.scss'
import Taro from "@tarojs/taro";
import avatar from '@/static/img/avatar.png'
interface Props extends ImageProps {
width?: number | string
height?: number | string
fallback?: string
errorType?: "acquiesce" | 'avatar'
}
const Img: FC<Props> = ({src, mode = 'aspectFill', width, height, fallback = shard, ...props}) => {
const [isError, setIsError] = useState(false)
const [loading, setLoading] = useState(true)
const [errorUrl, setErrorUrl] = useState(fallback)
const imgAnimation = Taro.createAnimation({duration: 0}).opacity(0).step()
const [animationData, setAnimationData] = useState<TaroGeneral.IAnyObject>(imgAnimation.export())
@ -22,6 +25,18 @@ const Img: FC<Props> = ({src, mode = 'aspectFill', width, height, fallback = sha
setLoading(!!src)
}, [src])
useEffect(() => {
switch (props.errorType) {
case undefined:
case "acquiesce":
setErrorUrl(fallback)
break
case "avatar":
setErrorUrl(avatar)
break
}
}, [props.errorType])
// 图片加载失败
function onErrorHandler() {
setLoading(false)
@ -40,8 +55,8 @@ const Img: FC<Props> = ({src, mode = 'aspectFill', width, height, fallback = sha
style={{
width: `${width}rpx`,
height: `${height}rpx`,
backgroundColor: '#F8F8F8'
}}
backgroundColor: (isError || !loading) ? 'transparent' : '#F8F8F8'
}}
className={`${props?.className} ${styles.imgBox}`}>
{!isError &&
<View animation={animationData}>
@ -51,8 +66,12 @@ const Img: FC<Props> = ({src, mode = 'aspectFill', width, height, fallback = sha
mode={mode}
lazyLoad
fadeIn
defaultSource={fallback}
style={{width: width ? `${width}rpx` : "100%", height: height ? `${height}rpx` : "100%"}}
defaultSource={errorUrl}
style={{
width: width ? `${width}rpx` : "100%",
height: height ? `${height}rpx` : "100%",
verticalAlign: 'middle'
}}
onError={onErrorHandler}
onLoad={onLoadHandler}/>
</View>
@ -62,7 +81,7 @@ const Img: FC<Props> = ({src, mode = 'aspectFill', width, height, fallback = sha
<Image
className={styles.imgError}
mode='aspectFill'
src={fallback}
src={errorUrl}
lazyLoad
fadeIn
style={{

@ -59,7 +59,6 @@ const LearningRecord: FC<Props> = ({userId}) => {
}, [userId])
return (<View className={styles.box} style={{display: 'block'}}>
<View className='font-weight font-32 mb-4'></View>
<Tabs tabList={tabList} onChange={tabChange} backMode/>
<View className={styles.total}>

@ -4,6 +4,7 @@ import styles from "@/pages/my/my.module.scss";
import avatar from "@/static/img/avatar.png"
import blacktriang from "@/static/img/blacktriangle.png"
import {FC} from "react";
import Img from "@/components/image/image";
interface Props {
companyList: Company[]
@ -16,13 +17,13 @@ const Header: FC<Props> = ({companyList, showCompany}) => {
return (
<View className={styles.header}>
<View className='flex'>
<Image src={user?.avatar || avatar} className={styles.avatar}/>
<Img width={100} height={100} src={user?.avatar || avatar} className={styles.avatar} errorType='avatar'/>
{
token ? <View className='flex-1 mt-1'>
<View className='font-32'>{user?.name}</View>
<View className='flex align-center mt-2' onClick={showCompany}>
<Text style={{fontSize: '24rpx', fontWeight: '500', color: '#323635'}}>{company?.name}</Text>
{companyList.length > 2 && <Image src={blacktriang} style={{width: '20rpx', height: '20rpx'}}></Image>}
{companyList.length > 2 && <Image src={blacktriang} style={{width: '20rpx', height: '20rpx'}}/>}
</View>
</View>
: <View className='flex-1'>

@ -4,6 +4,12 @@ page {
overflow-x: hidden;
}
.navigation {
transition: all 300ms;
display: flex;
align-items: center;
}
.page {
background: linear-gradient(180deg, #45D4A8 0%, rgba(69, 212, 168, 0) 100%) no-repeat;
background-size: 100% 458rpx;
@ -47,8 +53,6 @@ page {
font-size: 10rpx;
.avatar {
width: 100px;
height: 100px;
margin-right: 30px;
}
}
@ -59,7 +63,7 @@ page {
box-sizing: border-box;
height: 136rpx;
&:nth-child(n) {
&:nth-child(odd) {
padding-right: 11rpx;
}

@ -69,9 +69,10 @@ const My: FC = () => {
backgroundColor={`rgba(255,255,255,${navbarOpacity})`}
cancelBack>
{
Number(navbarOpacity) > .5 && <View className='flex align-center'>
<Img src={user?.avatar || avatar} mode='heightFix' width={60} height={60}/>
<Text className='pl-1'>{user?.name}</Text>
<View className={styles.navigation}
style={{transform: `translate(0,${Number(navbarOpacity) > .5 ? "0%" : '-300%'})`}}>
<Img src={user?.avatar || avatar} mode='heightFix' width={50} height={50} errorType='avatar'/>
<Text className='pl-2'>{user?.name}</Text>
</View>
}
</NavigationBar>
@ -139,7 +140,6 @@ const My: FC = () => {
</PageContainer>
</View>
</ScrollView>
</View>
)
}

@ -5,6 +5,7 @@ import Taro, {useReachBottom} from "@tarojs/taro";
import Empty from "@/components/empty/empty";
import Spinner from "@/components/spinner";
import Img from "@/components/image/image";
import {formatDate} from "@/utils/time";
const BrandItem: FC<{ data: BrandRecord; onClick: VoidFunction }> = ({data, onClick}) => {
let media: ReactNode
@ -41,14 +42,14 @@ const BrandItem: FC<{ data: BrandRecord; onClick: VoidFunction }> = ({data, onCl
<View className="text-row1 font-28">{data.name}</View>
</View>
</View>
<View className="font-24 text-muted mb-4 text-row3" style={{lineHeight:1.4}}>
<View className="font-24 text-muted mb-4 text-row3" style={{lineHeight: 1.4}}>
{data.graphic_introduction}
</View>
<View className="flex gap20rpx font-24 text-muted">
<View>2023/03.29 12:22:01</View>
<View>{formatDate(new Date(data.created_at), "YY-MM-dd hh:mm:ss")}</View>
<View className="flex-1"></View>
<View>123</View>
<View>234</View>
<View>{data.article_count}</View>
<View>{(Math.random() * 100).toFixed(0)}</View>
</View>
</View>
</View>
@ -108,7 +109,7 @@ const BrandList: FC = () => {
</>
)
} else {
content = <Empty name='空空如也'/>
content = <Empty name='暂无品牌入驻'/>
}
return (

Loading…
Cancel
Save