Merge remote-tracking branch 'origin/master'

v2
king 1 year ago
commit a318591244
  1. 8
      src/api/user.ts
  2. 1
      src/app.config.ts
  3. 4
      src/pages/my/components/header/service.tsx
  4. 1
      src/pages/my/my.tsx
  5. 3
      src/pages/preview/collect/collect.config.ts
  6. 63
      src/pages/preview/collect/collect.module.scss
  7. 197
      src/pages/preview/collect/collect.tsx
  8. 5
      src/pages/preview/search/search/components/list.module.scss
  9. 169
      src/pages/preview/search/search/components/list.tsx
  10. BIN
      src/static/img/icon-collect.png

@ -94,6 +94,14 @@ export const userApi = {
companyReplace(id: number) {
return request(`/api/v1/company/replace/${id}`, "PATCH")
},
// /** 上传头像 */
// putAvatar(file: string) {
// return request('/api/v1/user/avatar', "PUT", {file})
// }
/** 收藏列表 */
collectList(owner_type: number, page: number, page_size: number) {
return request<{ list: any[], total: number }>('/api/v1/collect/list', "GET", {owner_type, page, page_size})
},
/** 收藏 */
create(data: Create) {
return request("/api/v1/collect/create", "POST", data)

@ -93,6 +93,7 @@ export default defineAppConfig({
'illness/list/list',
'webView/webView',
'search/search/index',
'collect/collect', // 收藏列表
]
},
],

@ -8,7 +8,8 @@ import cur from '@/static/img/cur.png'
import userInfo from '@/static/img/userInfo.png'
import spotMeeting from '@/static/img/spotMeeting.png'
import course from '@/static/img/course.png'
import {userApi} from "@/api";
import collect from "@/static/img/icon-collect.png"
import {userApi} from "@/api"
interface List {
title: string;
@ -39,6 +40,7 @@ const Service = () => {
{title: '课程管理', src: course, router: '/pages/manage/courseAdmin/courseAdmin'},
{title: '个人中心', src: userInfo, router: '/pages/business/userInfo/userInfo'},
{title: '历史记录', src: cur, router: '/pages/business/history/history'},
{title: '我的收藏', src: collect, router: '/pages/preview/collect/collect'},
])
} else {
setList([

@ -15,6 +15,7 @@ import over from "@/static/img/over.png";
import incomplete from "@/static/img/incomplete.png";
import avatar from "@/static/img/avatar.png";
interface List {
title: string
time: string | number

@ -0,0 +1,3 @@
export default definePageConfig({
navigationBarTitleText: '收藏列表',
})

@ -0,0 +1,63 @@
.height {
height: calc(100vh - 80rpx - env(safe-area-inset-bottom));
overflow: hidden;
box-sizing: border-box;
}
.box {
margin-left:30rpx;
margin-bottom: 24rpx;
width:690rpx;
display: flex;
margin-bottom: 20rpx;
background-color: #fff;
border-radius: 16rpx;
padding: 24rpx;
box-sizing: border-box;
position: relative;
}
.image{
background-color: #ededed;
border-radius: 8rpx;
}
.play {
position: absolute;
z-index: 9999;
width: 50rpx !important;
height: 50rpx !important;
top: 99rpx;
left: 99rpx;
background: transparent !important;
}
.rightBox{
padding-left: 24rpx;
box-sizing: border-box;
flex: 1;
}
.articleLeftBox{
padding-right: 24rpx;
box-sizing: border-box;
flex: 1;
}
.videoRightBox{
padding-left: 24rpx;
box-sizing: border-box;
flex: 1;
}
.courseRightBox{
padding-left: 24rpx;
box-sizing: border-box;
flex: 1;
}
.desc{
font-size: 24rpx;
font-weight: 500;
color: #909795;
line-height: 34rpx;
display: -webkit-box;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
-webkit-box-orient:vertical;
-webkit-line-clamp:2;
}

@ -0,0 +1,197 @@
import {Image, ScrollView, Swiper, SwiperItem, View} from "@tarojs/components";
import {userApi} from "@/api";
import {useCallback, useEffect, useState} from "react";
import Tabs, {OnChangOpt, TabList} from "@/components/tabs/tabs";
import Empty from "@/components/empty/empty";
import Taro from "@tarojs/taro";
import styles from './collect.module.scss'
import Spin from "@/components/spinner";
import Img from "@/components/image/image";
import {rfc33392time} from "@/utils/day";
import play from "@/static/img/play.png";
interface KillData {
data: any[]
total: number
page: number
}
const Profession = () => {
const [tabs, setTabs] = useState<TabList[]>([])
const [categoryId, setCategoryId] = useState<number | null>(null)
const [data, setData] = useState<Map<number, KillData>>(new Map)
const [enable, setEnable] = useState(true)
/**
* more
*/
async function getData(more = false) {
if (!categoryId) return;
const oldData = new Map<number, KillData>(data)
const categoryData = oldData.get(categoryId)
const page = more ? (categoryData?.page || 0) + 1 : categoryData?.page || 1
/** 无更多 */
if (more && categoryData && categoryData.data.length >= categoryData.total) {
return
}
try {
const data = await userApi.collectList(categoryId!, page, 10)
// const dataList = data.list.reduce((pre, cur) => {
// const index = pre.findIndex(d => d.id === cur.id)
// if (index === -1) {
// pre.push(cur)
// } else {
// pre.splice(index, 1, cur)
// }
// return pre
// }, categoryData?.data || [])
oldData.delete(categoryId)
oldData.set(categoryId, {
data: data.list,
total: data.total,
page: page
})
setData(oldData)
} catch (e) {
}
}
Taro.useDidShow(useCallback(() => {
if(categoryId){
let tempMap = new Map()
tempMap.set(categoryId, {
data: [],
total: undefined,
page: 1
})
setData(tempMap)
getData()
}
},[data]))
useEffect(() => {
categoryId && getData()
}, [categoryId])
async function getCategory() {
try {
const res = [{name:'视频',id:2},{name:'文章',id:1},{name:'课程',id:3},{name:'其他',id:4}]
const newTabs = res.map<TabList>(d => ({title: d.name, value: d.id}))
setTabs(newTabs)
setCategoryId(newTabs[0].value as number)
} catch (e) {
}
setEnable(false)
}
function tabsChange(tab: OnChangOpt) {
setCategoryId(tab.tab?.value as number)
}
function jumpInfo(info: any) {
console.log(info,'info')
if(info.article){
Taro.navigateTo({url: `/pages/preview/brand/article/article?id=${info.owner_id}`})
}else if(info.course){
Taro.navigateTo({url: `/pages/business/videoInfo/videoInfo?id=${info.owner_id}`})
}else if(info.video_records){
Taro.navigateTo({url: `/pages/preview/videoFull/videoFull?id=${info.owner_id}`})
}else if(info.brand){
Taro.navigateTo({url: `/pages/preview/brand/info/info?id=${info.owner_id}`})
}
}
function swiperChange(e) {
const categoryId = tabs[e.target.current].value
setCategoryId(Number(categoryId))
}
Taro.useLoad(getCategory)
function KillList(data: KillData): JSX.Element {
if (!data?.data?.length) {
return <Empty name='暂无数据'/>
}
return (
<ScrollView
scrollY
onScrollToLower={() => getData(true)}
className={styles.height}>
{
data.data.map(d =>
<View onClick={() => jumpInfo(d)} className={styles.box} key={d.id}>
{
d.brand &&
<>
<Img width={128} height={128} src={d.brand.logo} mode='aspectFill' className={styles.image}/>
<View className={styles.rightBox}>
<View className='font-weight mb-2 font-28'>{d.brand.name}</View>
<View className={styles.desc}>{d.brand.graphic_introduction || '暂无品牌简介'}</View>
</View>
</>
}
{
d.article &&
<>
<View className={styles.articleLeftBox}>
<View className='font-weight mb-2 font-28 lh-40'>{d.article.title}</View>
<View className={styles.desc}>{rfc33392time(d.article.created_at)} {d.article.page_view}</View>
</View>
<Img width={172} height={128} src={d.article.logo} mode='aspectFill' className={styles.image}/>
</>
}
{
d.video_records &&
<>
<Img width={192} height={192} src={d.video_records.url_path} mode='aspectFill' className={styles.image}/>
<Image src={play} className={styles.play} mode='aspectFit'/>
<View className={styles.videoRightBox}>
<View className='font-weight mb-2 font-28 lh-40'>{d.video_records.title}</View>
<View className={styles.desc}>{d.video_records.introduction}</View>
<View className={`${styles.desc} mt-2`}>: {d.video_records.video_view}</View>
</View>
</>
}
{
d.course &&
<>
<Img width={192} height={138} src={d.course.thumb} mode='aspectFill' className={styles.image}/>
<View className={styles.courseRightBox}>
<View className='font-weight mb-2 font-28 lh-40'>{d.course.title}</View>
<View className={styles.desc}>:{d.course.class_hour} {d.course.charge}</View>
</View>
</>
}
</View>
)
}
<View className='text-center font-24 text-dark mt-2'></View>
</ScrollView>
)
}
return (
<>
<Spin enable={enable} overlay/>
<View className='bg-white'>
<Tabs tabList={tabs} onChange={tabsChange} current={categoryId!}/>
</View>
<Swiper
current={tabs.findIndex(d => d.value === categoryId)}
onChange={swiperChange}
className={styles.height}
style={{paddingTop: '10px'}}>
{
tabs.map(d => <SwiperItem key={d.title}>
{KillList(data.get(Number(d.value))!)}
</SwiperItem>)
}
</Swiper>
</>
)
}
export default Profession

@ -38,6 +38,11 @@
box-sizing: border-box;
flex: 1;
}
.courseRightBox{
padding-left: 24rpx;
box-sizing: border-box;
flex: 1;
}
.desc{
font-size: 24rpx;
font-weight: 500;

@ -4,17 +4,17 @@ import styles from './list.module.scss'
import Taro from "@tarojs/taro";
import Empty from "@/components/empty/empty";
import Img from "@/components/image/image";
import {SearchApi} from "@/api/search";
import {AtLoadMore} from 'taro-ui'
import { SearchApi } from "@/api/search";
import { AtLoadMore } from 'taro-ui'
import {rfc33392time} from "@/utils/day";
import play from "@/static/img/play.png";
type Props = {
name: string
clear: boolean
name:string
clear:boolean
}
const SearchList: FC<Props> = ({name, clear}) => {
console.log(name, 'name')
const SearchList: FC<Props> = ({name,clear}) => {
console.log(name,'name')
const globalData = Taro.getApp().globalData
const [page, setPage] = useState(1)
const [brands, setBrands] = useState<any[]>([])
@ -22,31 +22,31 @@ const SearchList: FC<Props> = ({name, clear}) => {
const [text, setText] = useState('')
const [loading, setLoading] = useState(true)
useEffect(() => {
if (!clear) {
useEffect(()=>{
if(!clear){
setBrands([])
setLoading(true)
}
}, [clear])
},[clear])
useEffect(() => {
if (name && clear) {
if(name && clear){
getData()
}
}, [page, name, clear])
}, [page,name,clear])
const getData = useCallback(async () => {
try {
const data = await SearchApi.list(page, 10, name)
const data = await SearchApi.list(page, 10,name)
if (page === 1) {
if (data.data.length < 10) {
setText('没有更多了')
setText('没有更多了~')
} else {
setText('上拉加载更多')
setText('上拉加载更多~')
}
setBrands([
...data.data
])
} else {
}else{
setBrands([
...brands,
...data.data
@ -57,24 +57,22 @@ const SearchList: FC<Props> = ({name, clear}) => {
} catch (e) {
}
setLoading(false)
}, [page, name])
}, [page,name])
function jumpInfo(id: number, type: string, health: any) {
console.log(type, 'type')
function jumpInfo(id: number,type:string) {
console.log(type,'type')
let url = ''
switch (type) {
switch (type){
case 'brand':
url = '/pages/preview/brand/info/info';
break;
case 'illness':
url = '/pages/preview/illness/list/list';
break;
case 'article':
url = '/pages/preview/brand/article/article'
break
case 'video_records':
return Taro.navigateTo({url: `/pages/preview/videoFull/videoFull?url=${health.resources.url}&poster=${health.url_path}&title=${health.title}`})
url = '/pages/preview/videoFull/videoFull'
break
case 'courses':
url = '/pages/business/videoInfo/videoInfo'
break
@ -83,13 +81,13 @@ const SearchList: FC<Props> = ({name, clear}) => {
}
function onScrollToLower() {
if (brands?.length < total) {
setPage(page + 1)
getData().then()
} else {
setText('没有更多了')
}
function onScrollToLower(){
if (brands?.length < total) {
setPage(page + 1)
getData().then()
} else {
setText('没有更多了~')
}
}
return (
@ -97,70 +95,65 @@ const SearchList: FC<Props> = ({name, clear}) => {
className='scrollview'
scrollY
scrollWithAnimation
style={{height: `${globalData.pageHeight - 20}px`, backgroundColor: `#f5f5f5`}}
style={{height:`${globalData.screenHeight-140}px`,backgroundColor:`#f5f5f5`}}
onScrollToLower={onScrollToLower}
>
{loading && <AtLoadMore status={'loading'}/>}
{ loading && <AtLoadMore status={'loading'}/>}
{
brands.length >= 1 && !loading &&
<>
{brands.map((d) =>
<View onClick={() => jumpInfo(d.data.id, d.data.table, d.data['@data'])} className={styles.box}
key={d.data.id}>
{
d.data.table === 'brand' &&
<>
<Img width={128} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/>
<View className={styles.rightBox}>
<View className='font-weight mb-2 font-28'>{d.data.title}</View>
<View className={styles.desc}>{d.data.content || '暂无品牌简介'}</View>
</View>
</>
}
{
d.data.table === 'article' &&
<>
<View className={styles.articleLeftBox}>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<View
className={styles.desc}>{rfc33392time(d.data['@data'].created_at)} {d.data['@data'].page_view}</View>
</View>
<Img width={172} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/>
</>
}
{
d.data.table === 'video_records' &&
<>
<Img width={192} height={192} src={d.data['@data'].url_path} mode='aspectFill'
className={styles.image}/>
<Image src={play} className={styles.play} mode='aspectFit'/>
<View className={styles.videoRightBox}>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<View className={styles.desc}>{d.data['@data'].introduction}</View>
<View className={`${styles.desc} mt-2`}>: {d.data['@data'].video_view}</View>
</View>
</>
}
{
d.data.table === 'courses' &&
<>
<Img width={192} height={138} src={d.data['@data'].thumb} mode='aspectFill' className={styles.image}/>
<View className={styles.articleLeftBox}>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<View className={styles.desc}>:{d.data['@data'].class_hour}
{d.data['@data'].charge}</View>
</View>
</>
}
<>
{brands.map((d) =>
<View onClick={() => jumpInfo(d.data.id,d.data.table)} className={styles.box} key={d.data.id}>
{
d.data.table === 'brand' &&
<>
<Img width={128} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/>
<View className={styles.rightBox}>
<View className='font-weight mb-2 font-28'>{d.data.title}</View>
<View className={styles.desc}>{d.data.content || '暂无品牌简介'}</View>
</View>
</>
}
{
d.data.table === 'article' &&
<>
<View className={styles.articleLeftBox}>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<View className={styles.desc}>{rfc33392time(d.data['@data'].created_at)} {d.data['@data'].page_view}</View>
</View>
<Img width={172} height={128} src={d.data['@data'].logo} mode='aspectFill' className={styles.image}/>
</>
}
{
d.data.table === 'video_records' &&
<>
<Img width={192} height={192} src={d.data['@data'].url_path} mode='aspectFill' className={styles.image}/>
<Image src={play} className={styles.play} mode='aspectFit'/>
<View className={styles.videoRightBox}>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<View className={styles.desc}>{d.data['@data'].introduction}</View>
<View className={`${styles.desc} mt-2`}>: {d.data['@data'].video_view}</View>
</View>
</>
}
{
d.data.table === 'courses' &&
<>
<Img width={192} height={138} src={d.data['@data'].thumb} mode='aspectFill' className={styles.image}/>
<View className={styles.courseRightBox}>
<View className='font-weight mb-2 font-28 lh-40'>{d.data['@data'].title}</View>
<View className={styles.desc}>:{d.data['@data'].class_hour} {d.data['@data'].charge}</View>
</View>
</>
}
</View>
)
}
<View className='text-center font-24 text-dark mt-3'>{text}</View>
</>
</View>
)
}
<View style={{width: '750rpx', textAlign: 'center', color: '#999'}} className="font-28 mt-3 mb-3">{text}</View>
</>
}
{!loading && brands.length === 0 && <Empty name='空空如也'/>}
{ !loading && brands.length === 0 && <Empty name='空空如也'/>}
</ScrollView>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Loading…
Cancel
Save