forked from gxwebsoft/mp-10550
优化细节
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '关于我们',
|
||||
navigationBarBackgroundColor: '#ffe0e0'
|
||||
})
|
||||
@@ -1,7 +0,0 @@
|
||||
function About() {
|
||||
return (
|
||||
<div>About</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default About
|
||||
@@ -1,3 +0,0 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '文章列表'
|
||||
})
|
||||
@@ -1,51 +0,0 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {ArrowRight} from '@nutui/icons-react-taro'
|
||||
import {pageCmsArticle} from "@/api/cms/cmsArticle";
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
||||
import Taro from '@tarojs/taro'
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
|
||||
/**
|
||||
* 文章终极列表
|
||||
* @constructor
|
||||
*/
|
||||
const Article = () => {
|
||||
const {params} = useRouter();
|
||||
const [categoryId, setCategoryId] = useState<number>(3494)
|
||||
const [list, setList] = useState<CmsArticle[]>([])
|
||||
|
||||
const reload = () => {
|
||||
if (params.id) {
|
||||
setCategoryId(Number(params.id))
|
||||
}
|
||||
pageCmsArticle({categoryId}).then(res => {
|
||||
if (res?.list) {
|
||||
setList(res?.list)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={'px-3 mb-10'}>
|
||||
<div className={'flex flex-col justify-between items-center bg-white rounded-lg p-4'}>
|
||||
<div className={'bg-white min-h-36 w-full'}>
|
||||
{
|
||||
list.map((item, index) => {
|
||||
return (
|
||||
<div key={index} className={'flex justify-between items-center py-2'} onClick={() => Taro.navigateTo({url: `/cms/help?id=${item.articleId}`}) }>
|
||||
<div className={'text-sm'}>{item.title}</div>
|
||||
<ArrowRight color={'#cccccc'} size={18} />
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Article
|
||||
25
src/cms/category/components/ArticleList.tsx
Normal file
25
src/cms/category/components/ArticleList.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import {Image, Cell} from '@nutui/nutui-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
|
||||
const ArticleList = (props: any) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={'px-3'}>
|
||||
{props.data.map((item, index) => {
|
||||
return (
|
||||
<Cell
|
||||
title={item.title}
|
||||
extra={
|
||||
<Image src={item.image} mode={'aspectFit'} lazyLoad={false} width={100} height="100"/>
|
||||
}
|
||||
key={index}
|
||||
onClick={() => Taro.navigateTo({url: '/cms/detail/index?id=' + item.articleId})}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default ArticleList
|
||||
54
src/cms/category/components/ArticleTabs.tsx
Normal file
54
src/cms/category/components/ArticleTabs.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {Tabs, Loading} from '@nutui/nutui-react-taro'
|
||||
import {pageCmsArticle} from "@/api/cms/cmsArticle";
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
||||
import ArticleList from "./ArticleList";
|
||||
|
||||
const ArticleTabs = (props: any) => {
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
const [tab1value, setTab1value] = useState<string | number>('0')
|
||||
const [list, setList] = useState<CmsArticle[]>([])
|
||||
|
||||
const reload = async (value) => {
|
||||
const {data} = props
|
||||
pageCmsArticle({categoryId: data[value].navigationId, page: 1, limit: 10}).then((res) => {
|
||||
res && setList(res?.list || [])
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
.finally(() => {
|
||||
setTab1value(value)
|
||||
setLoading(false)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload(0).then()
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Loading className={'px-2'}>加载中</Loading>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tabs
|
||||
value={tab1value}
|
||||
onChange={(value) => {
|
||||
reload(value).then()
|
||||
}}
|
||||
>
|
||||
{props.data?.map((item, index) => {
|
||||
return (
|
||||
<Tabs.TabPane title={item.categoryName} key={index}/>
|
||||
)
|
||||
})}
|
||||
</Tabs>
|
||||
<ArticleList data={list}/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default ArticleTabs
|
||||
31
src/cms/category/components/Banner.tsx
Normal file
31
src/cms/category/components/Banner.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Swiper } from '@nutui/nutui-react-taro'
|
||||
import {CmsAd} from "@/api/cms/cmsAd/model";
|
||||
import {Image} from '@nutui/nutui-react-taro'
|
||||
import {getCmsAd} from "@/api/cms/cmsAd";
|
||||
|
||||
const MyPage = () => {
|
||||
const [item, setItem] = useState<CmsAd>()
|
||||
const reload = () => {
|
||||
getCmsAd(439).then(data => {
|
||||
setItem(data)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Swiper defaultValue={0} height={item?.height} indicator style={{ height: item?.height + 'px', display: 'none' }}>
|
||||
{item?.imageList?.map((item) => (
|
||||
<Swiper.Item key={item}>
|
||||
<Image width="100%" height="100%" src={item.url} mode={'scaleToFill'} lazyLoad={false} style={{ height: item.height + 'px' }} />
|
||||
</Swiper.Item>
|
||||
))}
|
||||
</Swiper>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default MyPage
|
||||
4
src/cms/category/index.config.ts
Normal file
4
src/cms/category/index.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '文章列表',
|
||||
navigationBarTextStyle: 'black'
|
||||
})
|
||||
0
src/cms/category/index.scss
Normal file
0
src/cms/category/index.scss
Normal file
78
src/cms/category/index.tsx
Normal file
78
src/cms/category/index.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import Taro from '@tarojs/taro'
|
||||
import {useShareAppMessage, useShareTimeline} from "@tarojs/taro"
|
||||
import {Loading} from '@nutui/nutui-react-taro'
|
||||
import {useEffect, useState} from "react"
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import {getCmsNavigation, listCmsNavigation} from "@/api/cms/cmsNavigation";
|
||||
import {CmsNavigation} from "@/api/cms/cmsNavigation/model";
|
||||
import {pageCmsArticle} from "@/api/cms/cmsArticle";
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
||||
import ArticleList from './components/ArticleList'
|
||||
import ArticleTabs from "./components/ArticleTabs";
|
||||
import './index.scss'
|
||||
|
||||
function Category() {
|
||||
const {params} = useRouter();
|
||||
const [categoryId, setCategoryId] = useState<number>(0)
|
||||
const [category, setCategory] = useState<CmsNavigation[]>([])
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
const [nav, setNav] = useState<CmsNavigation>()
|
||||
const [list, setList] = useState<CmsArticle[]>([])
|
||||
|
||||
const reload = async () => {
|
||||
// 1.加载远程数据
|
||||
const id = Number(params.id)
|
||||
const nav = await getCmsNavigation(id)
|
||||
const categoryList = await listCmsNavigation({parentId: id})
|
||||
const shopGoods = await pageCmsArticle({categoryId: id})
|
||||
|
||||
// 2.赋值
|
||||
setCategoryId(id)
|
||||
setNav(nav)
|
||||
setList(shopGoods?.list || [])
|
||||
setCategory(categoryList)
|
||||
Taro.setNavigationBarTitle({
|
||||
title: `${nav?.categoryName}`
|
||||
})
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
reload().then(() => {
|
||||
setLoading(false)
|
||||
})
|
||||
}, []);
|
||||
|
||||
useShareTimeline(() => {
|
||||
return {
|
||||
title: `${nav?.categoryName}_时里院子市集`,
|
||||
path: `/shop/category/index?id=${categoryId}`
|
||||
};
|
||||
});
|
||||
|
||||
useShareAppMessage(() => {
|
||||
return {
|
||||
title: `${nav?.categoryName}_时里院子市集`,
|
||||
path: `/shop/category/index?id=${categoryId}`,
|
||||
success: function (res) {
|
||||
console.log('分享成功', res);
|
||||
},
|
||||
fail: function (res) {
|
||||
console.log('分享失败', res);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Loading className={'px-2'}>加载中</Loading>
|
||||
)
|
||||
}
|
||||
|
||||
if(category.length > 0){
|
||||
return <ArticleTabs data={category}/>
|
||||
}
|
||||
|
||||
return <ArticleList data={list}/>
|
||||
}
|
||||
|
||||
export default Category
|
||||
@@ -1,4 +0,0 @@
|
||||
.content{
|
||||
padding: 32px;
|
||||
line-height: 2.4rem;
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
import {useEffect, useState} from 'react'
|
||||
import {Image, Tag} from '@nutui/nutui-react-taro'
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import {Divider} from '@nutui/nutui-react-taro'
|
||||
import dayjs from 'dayjs'
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model"
|
||||
import {Eye, Clock, PickedUp, Purse, Coupon} from '@nutui/icons-react-taro'
|
||||
import AddCartBar from "@/components/AddCartBar";
|
||||
// 显示html富文本
|
||||
import {View, RichText} from '@tarojs/components'
|
||||
import './detail.scss'
|
||||
import Line from "@/components/Gap";
|
||||
import {wxParse} from "@/utils/common";
|
||||
import {getCmsArticle} from "@/api/cms/cmsArticle";
|
||||
|
||||
function Detail() {
|
||||
const {params} = useRouter();
|
||||
// 文章详情
|
||||
const [item, setItem] = useState<CmsArticle>()
|
||||
// 浏览量
|
||||
const [views, setViews] = useState<number>()
|
||||
// 报名人数
|
||||
const [bmUsers, setBmUsers] = useState<number>()
|
||||
|
||||
const reload = () => {
|
||||
getCmsArticle(Number(params.id)).then(data => {
|
||||
if(data){
|
||||
data.content = wxParse(data.content)
|
||||
setItem(data)
|
||||
setViews(data.actualViews)
|
||||
setBmUsers(data.bmUsers)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={'bg-white'}>
|
||||
<Image src={item?.image} height={375} className={'bg-gray-50'}/>
|
||||
<div className={'p-3 font-bold text-lg'}>{item?.title}</div>
|
||||
<div className={'flex justify-between px-3'}>
|
||||
<Tag type={'success'}>{item?.categoryName}</Tag>
|
||||
<div className={'flex items-center gap-2 text-sm text-gray-400'}><Eye size={14}/>{views}</div>
|
||||
</div>
|
||||
{
|
||||
item?.model == 'pay' ? '' :
|
||||
<div className={'pt-2'}>
|
||||
{
|
||||
!item?.endTime ? '' :
|
||||
<div className={'flex px-3 py-1 items-center gap-2'}>
|
||||
<Clock size={14}/>
|
||||
<div
|
||||
className={'text-sm font-bold'}>{dayjs(item?.startTime).format('YYYY-MM-DD')} 至 {dayjs(item?.endTime).format('YYYY-MM-DD')}</div>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
!item?.price ? '' :
|
||||
<>
|
||||
<div className={'flex px-3 py-1 items-center gap-2'}>
|
||||
<Purse size={14}/>
|
||||
<div
|
||||
className={'text-sm font-bold'}>{item?.price == 0 ? '线下收费' : '¥' + item?.price}
|
||||
</div>
|
||||
</div>
|
||||
<Divider/>
|
||||
</>
|
||||
}
|
||||
<div className={'flex px-3 items-center gap-2'}>
|
||||
<PickedUp size={14}/>
|
||||
<div
|
||||
className={'text-sm font-bold'}>已报名 {bmUsers} 人 / 仅限校友报名
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<Divider/>
|
||||
<div className={'flex px-3 items-center gap-2'}>
|
||||
<Coupon size={14}/>
|
||||
<div
|
||||
className={'text-sm font-bold bg-white'}>活动详情
|
||||
</div>
|
||||
</div>
|
||||
<View className={'content text-gray-700 text-sm'}>
|
||||
<RichText nodes={item?.content}/>
|
||||
</View>
|
||||
<Line height={44}/>
|
||||
<AddCartBar />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Detail
|
||||
@@ -1,50 +0,0 @@
|
||||
.article-detail-page {
|
||||
padding: 15px;
|
||||
background-color: #fff;
|
||||
|
||||
.article-header {
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 15px;
|
||||
|
||||
.article-title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.article-meta {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
|
||||
span {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.article-content {
|
||||
line-height: 1.8;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
|
||||
.article-main-image {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,53 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {Image} from '@nutui/nutui-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
||||
import {useEffect, useState} from 'react'
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import {Loading} from '@nutui/nutui-react-taro'
|
||||
import {View, RichText} from '@tarojs/components'
|
||||
import {wxParse} from "@/utils/common";
|
||||
import {getCmsArticle} from "@/api/cms/cmsArticle";
|
||||
import dayjs from "dayjs";
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model"
|
||||
import Line from "@/components/Gap";
|
||||
import './index.scss'
|
||||
|
||||
const ArticleDetail = () => {
|
||||
const [article, setArticle] = useState<CmsArticle | null>(null);
|
||||
const router = Taro.getCurrentInstance().router;
|
||||
const articleId = router?.params?.id;
|
||||
function Detail() {
|
||||
const {params} = useRouter();
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
// 文章详情
|
||||
const [item, setItem] = useState<CmsArticle>()
|
||||
const reload = async () => {
|
||||
const item = await getCmsArticle(Number(params.id))
|
||||
|
||||
if (item) {
|
||||
item.content = wxParse(item.content)
|
||||
setItem(item)
|
||||
Taro.setNavigationBarTitle({
|
||||
title: `${item?.categoryName}`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (articleId) {
|
||||
getCmsArticle(Number(articleId)).then(res => {
|
||||
setArticle(res);
|
||||
}).catch(error => {
|
||||
console.error("Failed to fetch article detail:", error);
|
||||
});
|
||||
}
|
||||
}, [articleId]);
|
||||
reload().then(() => {
|
||||
setLoading(false)
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (!article) {
|
||||
return <div>加载中...</div>;
|
||||
if (loading) {
|
||||
return (
|
||||
<Loading className={'px-2'}>加载中</Loading>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={'article-detail-page'}>
|
||||
<div className={'article-header'}>
|
||||
<h1 className={'article-title'}>{article.title}</h1>
|
||||
<div className={'article-meta'}>
|
||||
<span>作者:{article.author}</span>
|
||||
<span>发布时间:{dayjs(article.createTime).format('YYYY-MM-DD HH:mm')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'article-content'}>
|
||||
{article.image && <Image src={article.image} className={'article-main-image'} />}
|
||||
<div dangerouslySetInnerHTML={{ __html: article.content || '' }} />
|
||||
</div>
|
||||
<div className={'bg-white'}>
|
||||
<div className={'p-4 font-bold text-lg'}>{item?.title}</div>
|
||||
<div className={'text-gray-400 text-sm px-4 '}>{item?.createTime}</div>
|
||||
<View className={'content px-3'}>
|
||||
<RichText nodes={item?.content}/>
|
||||
</View>
|
||||
<Line height={44}/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default ArticleDetail;
|
||||
export default Detail
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '文章详情'
|
||||
})
|
||||
@@ -1,45 +0,0 @@
|
||||
import {useEffect, useState} from 'react'
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model"
|
||||
// import ReactMarkdown from 'react-markdown';
|
||||
// 显示html富文本
|
||||
import {View, RichText} from '@tarojs/components'
|
||||
import './detail.scss'
|
||||
import Line from "@/components/Gap";
|
||||
import {wxParse} from "@/utils/common";
|
||||
import {getCmsArticle} from "@/api/cms/cmsArticle";
|
||||
|
||||
function Detail() {
|
||||
const {params} = useRouter();
|
||||
// 文章详情
|
||||
const [item, setItem] = useState<CmsArticle>()
|
||||
const reload = () => {
|
||||
getCmsArticle(Number(params.id)).then(data => {
|
||||
if(data){
|
||||
data.content = wxParse(data.content)
|
||||
setItem(data)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={'bg-white'}>
|
||||
<div className={'p-4 font-bold text-lg'}>{item?.title}</div>
|
||||
<div className={'text-gray-400 text-sm px-4 '}>{item?.createTime}</div>
|
||||
<View className={'content text-gray-700 text-sm'}>
|
||||
{
|
||||
item?.editor === 1 ?
|
||||
<RichText nodes={item?.content} /> :
|
||||
null
|
||||
}
|
||||
</View>
|
||||
<Line height={44}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Detail
|
||||
Reference in New Issue
Block a user