forked from gxwebsoft/mp-10550
提交代码
This commit is contained in:
3
src/pages/article/article.config.ts
Normal file
3
src/pages/article/article.config.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '学习'
|
||||
})
|
||||
50
src/pages/article/article.tsx
Normal file
50
src/pages/article/article.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
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'
|
||||
|
||||
/**
|
||||
* 文章终极列表
|
||||
* @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({}).then(res => {
|
||||
if (res?.list) {
|
||||
setList(res?.list)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={'px-3 mt-4 mb-10'}>
|
||||
<div className={'flex flex-col justify-between items-center bg-white rounded-lg p-4'}>
|
||||
<div className={'bg-white 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
|
||||
4
src/pages/find/find.config.ts
Normal file
4
src/pages/find/find.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '发现',
|
||||
navigationStyle: 'custom',
|
||||
})
|
||||
4
src/pages/find/find.scss
Normal file
4
src/pages/find/find.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
page {
|
||||
background: linear-gradient(to bottom, #e9fff2, #f9fafb);
|
||||
background-size: 100%;
|
||||
}
|
||||
75
src/pages/find/find.tsx
Normal file
75
src/pages/find/find.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import Taro from '@tarojs/taro';
|
||||
import {pageCmsArticle} from "@/api/cms/cmsArticle";
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
||||
import {checkMonthTaskCompleted} from "@/api/hjm/hjmExamLog";
|
||||
import {NavBar, Space} from '@nutui/nutui-react-taro'
|
||||
import {getWebsiteField} from "@/api/system/website/field";
|
||||
import './find.scss'
|
||||
|
||||
/**
|
||||
* 文章终极列表
|
||||
* @constructor
|
||||
*/
|
||||
const Find = () => {
|
||||
const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
||||
const [isAdmin, setIsAdmin] = useState<boolean>(false)
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const [list, setList] = useState<CmsArticle[]>()
|
||||
const [monthTaskCompleted, setMonthTaskCompleted] = useState<boolean>(false)
|
||||
|
||||
const reload = async () => {
|
||||
setLoading(true)
|
||||
const field = await getWebsiteField(15524);
|
||||
if (field.value == '0') {
|
||||
setIsAdmin(true)
|
||||
}else {
|
||||
setIsAdmin(false)
|
||||
}
|
||||
const article = await pageCmsArticle({categoryId: 4289, status: 0})
|
||||
if(article){
|
||||
setList(article?.list)
|
||||
}
|
||||
const promise = await checkMonthTaskCompleted();
|
||||
if(promise){
|
||||
setMonthTaskCompleted(true)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
Taro.getSystemInfo({
|
||||
success: (res) => {
|
||||
setStatusBarHeight(res.statusBarHeight)
|
||||
},
|
||||
})
|
||||
reload().then(() => {
|
||||
console.log('初始化完成')
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavBar
|
||||
fixed={true}
|
||||
style={{marginTop: `${statusBarHeight}px`, backgroundColor: 'transparent'}}
|
||||
onBackClick={() => {
|
||||
}}
|
||||
left={
|
||||
<>
|
||||
<div className={'flex justify-between items-center w-full'}>
|
||||
|
||||
</div>
|
||||
{/*<SearchBar shape="round" maxLength={5} style={{paddingLeft: '1px'}}/>*/}
|
||||
{/*<div className={'flex flex-col text-center justify-center items-center'}>*/}
|
||||
{/* <Filter size={14}/>*/}
|
||||
{/* <div className={'text-xs text-gray-600 whitespace-nowrap'}>筛选</div>*/}
|
||||
{/*</div>*/}
|
||||
</>
|
||||
}
|
||||
>
|
||||
<span>发现</span>
|
||||
</NavBar>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default Find
|
||||
31
src/pages/index/Banner.tsx
Normal file
31
src/pages/index/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(433).then(data => {
|
||||
setItem(data)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Swiper defaultValue={0} height={item?.height} indicator style={{ height: item?.height, display: 'none' }}>
|
||||
{item?.imageList?.map((item) => (
|
||||
<Swiper.Item key={item}>
|
||||
<Image width="100%" height="100%" src={item.url} mode={'scaleToFill'} style={{ height: item.height }} />
|
||||
</Swiper.Item>
|
||||
))}
|
||||
</Swiper>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default MyPage
|
||||
15
src/pages/index/BestSellers.scss
Normal file
15
src/pages/index/BestSellers.scss
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
.buy-btn{
|
||||
height: 70px;
|
||||
background: linear-gradient(to bottom, #1cd98a, #24ca94);
|
||||
border-radius: 100px;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
.cart-icon{
|
||||
background: linear-gradient(to bottom, #bbe094, #4ee265);
|
||||
border-radius: 100px 0 0 100px;
|
||||
height: 70px;
|
||||
}
|
||||
}
|
||||
230
src/pages/index/BestSellers.tsx
Normal file
230
src/pages/index/BestSellers.tsx
Normal file
@@ -0,0 +1,230 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {Image, Space, Tag, Divider} from '@nutui/nutui-react-taro'
|
||||
import {Cart} from '@nutui/icons-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
||||
import {pageShopGoods} from "@/api/shop/shopGoods";
|
||||
import './BestSellers.scss'
|
||||
|
||||
const goodsList = [
|
||||
{
|
||||
goodsId: 1,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 2,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 3,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 4,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 5,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 6,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 7,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 8,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 9,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 10,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 11,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 12,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 13,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 14,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 15,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 16,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 17,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 18,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 19,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
},
|
||||
{
|
||||
goodsId: 20,
|
||||
code: '123456',
|
||||
goodsName: '【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋',
|
||||
unitName: '测试单位',
|
||||
sales: '1.2万',
|
||||
image: 'https://oss.wsdns.cn/20250622/84f4a3e981584b1fb8e4b3898aa07cb7.jpg'
|
||||
}
|
||||
]
|
||||
|
||||
const BestSellers = () => {
|
||||
const [list, setList] = useState<ShopGoods[]>([])
|
||||
const reload = () => {
|
||||
pageShopGoods({}).then(res => {
|
||||
setList(res?.list || []);
|
||||
})
|
||||
console.log(list)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={'py-0'}>
|
||||
<div className={'flex flex-col justify-between items-center rounded-lg px-2'}>
|
||||
{goodsList?.map((item, index) => {
|
||||
return (
|
||||
<div key={index} className={'flex flex-col rounded-lg bg-white shadow-sm w-full mb-5'}
|
||||
onClick={() => Taro.navigateTo({url: '/hjm/location?id=' + item.goodsId})}>
|
||||
<Image src={item.image} mode={'scaleToFill'}
|
||||
radius="10px 10px 0 0" height="180"/>
|
||||
<div className={'flex flex-col p-2 rounded-lg'}>
|
||||
<div>
|
||||
<div className={'car-no text-sm'}>{item.goodsName} #{item.goodsId}</div>
|
||||
<div className={'flex justify-between text-xs py-1'}>
|
||||
<span className={'text-orange-500'}>丰江桥佛手瓜面,非油炸,Q弹爽口,营养丰</span>
|
||||
<span className={'text-gray-400'}>已售 {item.sales}</span>
|
||||
</div>
|
||||
<Space>
|
||||
<Tag plain round background={'#ff0000'}>会客厅循环劵<Divider direction={'vertical'} style={{
|
||||
borderStyle: 'dashed', padding: '0',
|
||||
borderColor: '#fd8989', margin: '0 5px'
|
||||
}}/>每拍2减10元</Tag>
|
||||
<Tag plain round background={'#ff0000'}>会客厅专享<Divider direction={'vertical'} style={{
|
||||
borderStyle: 'dashed', padding: '0',
|
||||
borderColor: '#fd8989', margin: '0 5px'
|
||||
}}/>拍1减3元</Tag>
|
||||
</Space>
|
||||
<div className={'flex justify-between items-center py-2'}>
|
||||
<div className={'flex text-red-500 text-xl items-baseline'}>
|
||||
<span className={'text-xs'}>¥</span>
|
||||
<span className={'font-bold text-2xl'}>19.9</span>
|
||||
</div>
|
||||
<div className={'buy-btn'}>
|
||||
<div className={'cart-icon'}><Cart size={20} className={'mx-4 mt-2'} /></div>
|
||||
<div className={'text-white pl-4 pr-5'}>购买</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default BestSellers
|
||||
69
src/pages/index/Chart.tsx
Normal file
69
src/pages/index/Chart.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {Tabs, TabPane} from '@nutui/nutui-react-taro'
|
||||
|
||||
const list = [
|
||||
{
|
||||
title: '今天',
|
||||
id: 1
|
||||
},
|
||||
{
|
||||
title: '昨天',
|
||||
id: 2
|
||||
},
|
||||
{
|
||||
title: '过去7天',
|
||||
id: 3
|
||||
},
|
||||
{
|
||||
title: '过去30天',
|
||||
id: 4
|
||||
}
|
||||
]
|
||||
const Chart = () => {
|
||||
const [tapIndex, setTapIndex] = useState<string | number>('0')
|
||||
const reload = () => {
|
||||
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tabs
|
||||
align={'left'}
|
||||
tabStyle={{position: 'sticky', top: '0px'}}
|
||||
value={tapIndex}
|
||||
onChange={(paneKey) => {
|
||||
setTapIndex(paneKey)
|
||||
}}
|
||||
>
|
||||
{
|
||||
list?.map((item, index) => {
|
||||
return (
|
||||
<TabPane key={index} title={item.title}/>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Tabs>
|
||||
{
|
||||
list?.map((item, index) => {
|
||||
console.log(item.title)
|
||||
return (
|
||||
<div key={index} className={'px-3'}>
|
||||
{
|
||||
tapIndex != index ? null :
|
||||
<div className={'bg-white rounded-lg p-4 flex justify-center items-center text-center text-gray-300'} style={{height: '200px'}}>
|
||||
线状图
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
export default Chart
|
||||
83
src/pages/index/ExpirationTime.tsx
Normal file
83
src/pages/index/ExpirationTime.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import Taro from '@tarojs/taro'
|
||||
import {Button} from '@nutui/nutui-react-taro'
|
||||
import {Target, Scan, Truck} from '@nutui/icons-react-taro'
|
||||
import {getUserInfo} from "@/api/layout";
|
||||
import navTo from "@/utils/common";
|
||||
|
||||
const ExpirationTime = () => {
|
||||
const [isAdmin, setIsAdmin] = useState<boolean>(false)
|
||||
const [roleName, setRoleName] = useState<string>()
|
||||
const onScanCode = () => {
|
||||
Taro.scanCode({
|
||||
onlyFromCamera: true,
|
||||
scanType: ['qrCode'],
|
||||
success: (res) => {
|
||||
console.log(res, 'qrcode...')
|
||||
Taro.navigateTo({url: '/hjm/query?id=' + res.result})
|
||||
},
|
||||
fail: (res) => {
|
||||
console.log(res, '扫码失败')
|
||||
Taro.showToast({
|
||||
title: '扫码失败',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const navToCarList = () => {
|
||||
if (isAdmin) {
|
||||
navTo('/hjm/list', true)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getUserInfo().then((data) => {
|
||||
if (data) {
|
||||
if(data.certification){
|
||||
setIsAdmin( true)
|
||||
}
|
||||
data.roles?.map((item, index) => {
|
||||
if (index == 0) {
|
||||
setRoleName(item.roleCode)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={'mb-3 fixed top-36 z-20'} style={{width: '96%', marginLeft: '3%'}}>
|
||||
<div className={'w-full flex justify-around items-center py-3 rounded-lg'}>
|
||||
<>
|
||||
<Button size={'large'}
|
||||
style={{background: 'linear-gradient(to right, #f3f2f7, #805de1)', borderColor: '#f3f2f7'}}
|
||||
icon={<Truck/>} onClick={navToCarList}>车辆列表</Button>
|
||||
<Button size={'large'}
|
||||
style={{background: 'linear-gradient(to right, #fffbe6, #ffc53d)', borderColor: '#f3f2f7'}}
|
||||
icon={<Scan/>}
|
||||
onClick={onScanCode}>扫一扫
|
||||
</Button>
|
||||
</>
|
||||
|
||||
{
|
||||
roleName == 'youzheng' && <Button size={'large'} style={{
|
||||
background: 'linear-gradient(to right, #eaff8f, #7cb305)',
|
||||
borderColor: '#f3f2f7'
|
||||
}} icon={<Target/>} onClick={() => Taro.navigateTo({url: '/hjm/fence'})}>电子围栏</Button>
|
||||
}
|
||||
|
||||
{
|
||||
roleName == 'kuaidiyuan' && <Button size={'large'} style={{
|
||||
background: 'linear-gradient(to right, #ffa39e, #ff4d4f)',
|
||||
borderColor: '#f3f2f7'
|
||||
}} icon={<Target/>} onClick={() => Taro.navigateTo({url: '/hjm/bx/bx-add'})}>一键报险</Button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default ExpirationTime
|
||||
183
src/pages/index/Header.tsx
Normal file
183
src/pages/index/Header.tsx
Normal file
@@ -0,0 +1,183 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import Taro from '@tarojs/taro';
|
||||
import {Button, Space} from '@nutui/nutui-react-taro'
|
||||
import {TriangleDown} from '@nutui/icons-react-taro'
|
||||
import {Popup, Avatar, NavBar} from '@nutui/nutui-react-taro'
|
||||
import {getSiteInfo, getUserInfo, getWxOpenId} from "@/api/layout";
|
||||
import {TenantId} from "@/utils/config";
|
||||
import {getOrganization} from "@/api/system/organization";
|
||||
import {myUserVerify} from "@/api/system/userVerify";
|
||||
import {CmsWebsite} from "@/api/cms/cmsWebsite/model";
|
||||
import {User} from "@/api/system/user/model";
|
||||
|
||||
const Header = () => {
|
||||
const [userInfo, setUserInfo] = useState<User>()
|
||||
const [IsLogin, setIsLogin] = useState<boolean>(true)
|
||||
const [config, setConfig] = useState<CmsWebsite>()
|
||||
const [showBasic, setShowBasic] = useState(false)
|
||||
const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
||||
|
||||
const reload = async () => {
|
||||
Taro.getSystemInfo({
|
||||
success: (res) => {
|
||||
setStatusBarHeight(res.statusBarHeight)
|
||||
},
|
||||
})
|
||||
// 获取站点信息
|
||||
getSiteInfo().then((data) => {
|
||||
setConfig(data);
|
||||
console.log(userInfo)
|
||||
})
|
||||
// 获取用户信息
|
||||
getUserInfo().then((data) => {
|
||||
if (data) {
|
||||
setIsLogin(true);
|
||||
setUserInfo(data)
|
||||
console.log('用户信息>>>',data.phone)
|
||||
// 保存userId
|
||||
Taro.setStorageSync('UserId', data.userId)
|
||||
// 获取openId
|
||||
if (!data.openid) {
|
||||
Taro.login({
|
||||
success: (res) => {
|
||||
getWxOpenId({code: res.code}).then(() => {
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 是否已认证
|
||||
if(data.certification){
|
||||
Taro.setStorageSync('Certification','1')
|
||||
}
|
||||
// 机构ID
|
||||
Taro.setStorageSync('OrganizationId',data.organizationId)
|
||||
// 父级机构ID
|
||||
if(Number(data.organizationId) > 0){
|
||||
getOrganization(Number(data.organizationId)).then(res => {
|
||||
Taro.setStorageSync('OrganizationParentId',res.parentId)
|
||||
})
|
||||
}
|
||||
// 管理员
|
||||
const isKdy = data.roles?.findIndex(item => item.roleCode == 'admin')
|
||||
if(isKdy != -1){
|
||||
Taro.setStorageSync('RoleName', '管理')
|
||||
Taro.setStorageSync('RoleCode', 'admin')
|
||||
return false;
|
||||
}
|
||||
// 注册用户
|
||||
const isUser = data.roles?.findIndex(item => item.roleCode == 'user')
|
||||
if(isUser != -1){
|
||||
Taro.setStorageSync('RoleName', '注册用户')
|
||||
Taro.setStorageSync('RoleCode', 'user')
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}).catch(() => {
|
||||
setIsLogin(false);
|
||||
console.log('未登录')
|
||||
});
|
||||
// 认证信息
|
||||
myUserVerify({status: 1}).then(data => {
|
||||
if(data?.realName){
|
||||
Taro.setStorageSync('RealName',data.realName)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* 获取用户手机号 */
|
||||
const handleGetPhoneNumber = ({detail}) => {
|
||||
const {code, encryptedData, iv} = detail
|
||||
Taro.login({
|
||||
success: function () {
|
||||
if (code) {
|
||||
Taro.request({
|
||||
url: 'https://server.gxwebsoft.com/api/wx-login/loginByMpWxPhone',
|
||||
method: 'POST',
|
||||
data: {
|
||||
code,
|
||||
encryptedData,
|
||||
iv,
|
||||
notVerifyPhone: true,
|
||||
refereeId: 0,
|
||||
sceneType: 'save_referee',
|
||||
tenantId: TenantId
|
||||
},
|
||||
header: {
|
||||
'content-type': 'application/json',
|
||||
TenantId
|
||||
},
|
||||
success: function (res) {
|
||||
if(res.data.code == 1){
|
||||
Taro.showToast({
|
||||
title: res.data.message,
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
})
|
||||
return false;
|
||||
}
|
||||
// 登录成功
|
||||
Taro.setStorageSync('access_token', res.data.data.access_token)
|
||||
Taro.setStorageSync('UserId', res.data.data.user.userId)
|
||||
setIsLogin(true)
|
||||
// 重新加载小程序
|
||||
Taro.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('登录失败!')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavBar
|
||||
style={{marginTop: `${statusBarHeight}px`, marginBottom: '0px', backgroundColor: 'transparent'}}
|
||||
onBackClick={() => {
|
||||
}}
|
||||
left={
|
||||
!IsLogin ? (
|
||||
<div style={{display: 'flex', alignItems: 'center'}}>
|
||||
<Button style={{color: '#000'}} open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
|
||||
<Space>
|
||||
<Avatar
|
||||
size="22"
|
||||
src={config?.websiteLogo}
|
||||
/>
|
||||
<span style={{color: '#000'}}>{config?.websiteName}</span>
|
||||
</Space>
|
||||
</Button>
|
||||
<TriangleDown size={9}/>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{display: 'flex', alignItems: 'center', gap: '8px'}}>
|
||||
<Avatar
|
||||
size="22"
|
||||
src={config?.websiteLogo}
|
||||
/>
|
||||
{config?.websiteName}
|
||||
<TriangleDown size={9}/>
|
||||
</div>
|
||||
)}>
|
||||
</NavBar>
|
||||
<Popup
|
||||
visible={showBasic}
|
||||
position="bottom"
|
||||
style={{width: '100%', height: '100%'}}
|
||||
onClose={() => {
|
||||
setShowBasic(false)
|
||||
}}
|
||||
>
|
||||
<div style={{padding: '12px 0', fontWeight: 'bold', textAlign: 'center'}}>车辆信息</div>
|
||||
</Popup>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default Header
|
||||
68
src/pages/index/Help.tsx
Normal file
68
src/pages/index/Help.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {ArrowRight} from '@nutui/icons-react-taro'
|
||||
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
||||
import Taro from '@tarojs/taro'
|
||||
import {useRouter} from '@tarojs/taro'
|
||||
import {BaseUrl} from "@/utils/config";
|
||||
import {TEMPLATE_ID} from "@/utils/server";
|
||||
|
||||
/**
|
||||
* 帮助中心
|
||||
* @constructor
|
||||
*/
|
||||
const Help = () => {
|
||||
const {params} = useRouter();
|
||||
const [categoryId, setCategoryId] = useState<number>(3494)
|
||||
const [list, setList] = useState<CmsArticle[]>([])
|
||||
|
||||
const reload = () => {
|
||||
if (params.id) {
|
||||
setCategoryId(Number(params.id))
|
||||
}
|
||||
Taro.request({
|
||||
url: BaseUrl + '/cms/cms-article/page',
|
||||
method: 'GET',
|
||||
data: {
|
||||
categoryId
|
||||
},
|
||||
header: {
|
||||
'content-type': 'application/json',
|
||||
TenantId: TEMPLATE_ID
|
||||
},
|
||||
success: function (res) {
|
||||
const data = res.data.data;
|
||||
if (data?.list) {
|
||||
setList(data?.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={'title-bar flex justify-between items-center w-full mb-2'}>
|
||||
<div className={'font-bold text-lg flex text-gray-800 justify-center items-center'}>帮助中心</div>
|
||||
<a className={'text-gray-400 text-sm'} onClick={() => Taro.navigateTo({url: `/cms/article?id=${categoryId}`})}>查看全部</a>
|
||||
</div>
|
||||
<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 Help
|
||||
106
src/pages/index/Login.tsx
Normal file
106
src/pages/index/Login.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import Taro from '@tarojs/taro'
|
||||
import {Input, Radio, Button} from '@nutui/nutui-react-taro'
|
||||
import {TenantId} from "@/utils/config";
|
||||
import './login.scss';
|
||||
import {saveStorageByLoginUser} from "@/utils/server";
|
||||
|
||||
const Login = (props:any) => {
|
||||
const [isAgree, setIsAgree] = useState(false)
|
||||
const [env, setEnv] = useState<string>()
|
||||
|
||||
/* 获取用户手机号 */
|
||||
const handleGetPhoneNumber = ({detail}) => {
|
||||
const {code, encryptedData, iv} = detail
|
||||
Taro.login({
|
||||
success: function () {
|
||||
if (code) {
|
||||
Taro.request({
|
||||
url: 'https://server.gxwebsoft.com/api/wx-login/loginByMpWxPhone',
|
||||
method: 'POST',
|
||||
data: {
|
||||
code,
|
||||
encryptedData,
|
||||
iv,
|
||||
notVerifyPhone: true,
|
||||
refereeId: 0,
|
||||
sceneType: 'save_referee',
|
||||
tenantId: TenantId
|
||||
},
|
||||
header: {
|
||||
'content-type': 'application/json',
|
||||
TenantId
|
||||
},
|
||||
success: function (res) {
|
||||
saveStorageByLoginUser(res.data.data.access_token,res.data.data.user)
|
||||
props.done(res.data.data.user);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('登录失败!')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const reload = () => {
|
||||
Taro.hideTabBar()
|
||||
setEnv(Taro.getEnv())
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{height: '80vh'}} className={'flex flex-col justify-center px-5'}>
|
||||
<div className={'text-3xl text-center py-5 font-normal mb-10 '}>登录</div>
|
||||
{
|
||||
env === 'WEAPP' && (
|
||||
<>
|
||||
<div className={'flex flex-col w-full text-white rounded-full justify-between items-center my-2'} style={{ background: 'linear-gradient(to right, #7e22ce, #9333ea)'}}>
|
||||
<Button open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
|
||||
授权手机号登录
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
{
|
||||
env === 'WEB' && (
|
||||
<>
|
||||
<div className={'flex flex-col justify-between items-center my-2'}>
|
||||
<Input type="text" placeholder="手机号" maxLength={11}
|
||||
style={{backgroundColor: '#ffffff', borderRadius: '8px'}}/>
|
||||
</div>
|
||||
<div className={'flex flex-col justify-between items-center my-2'}>
|
||||
<Input type="password" placeholder="密码" style={{backgroundColor: '#ffffff', borderRadius: '8px'}}/>
|
||||
</div>
|
||||
<div className={'flex justify-between my-2 text-left px-1'}>
|
||||
<a href={'#'} className={'text-blue-600 text-sm'}
|
||||
onClick={() => Taro.navigateTo({url: '/passport/forget'})}>忘记密码</a>
|
||||
<a href={'#'} className={'text-blue-600 text-sm'}
|
||||
onClick={() => Taro.navigateTo({url: '/passport/setting'})}>服务配置</a>
|
||||
</div>
|
||||
<div className={'flex justify-center my-5'}>
|
||||
<Button type="info" size={'large'} className={'w-full rounded-lg p-2'} disabled={!isAgree}>登录</Button>
|
||||
</div>
|
||||
<div className={'w-full bottom-20 my-2 flex justify-center text-sm items-center text-center'}>
|
||||
没有账号?<a href={''} onClick={() => Taro.navigateTo({url: '/passport/register'})}
|
||||
className={'text-blue-600'}>立即注册</a>
|
||||
</div>
|
||||
<div className={'my-2 flex fixed bottom-20 text-sm items-center px-1'}>
|
||||
<Radio style={{color: '#333333'}} checked={isAgree} onClick={() => setIsAgree(!isAgree)}></Radio>
|
||||
<span className={'text-gray-400'} onClick={() => setIsAgree(!isAgree)}>登录表示您已阅读并同意</span><a
|
||||
onClick={() => Taro.navigateTo({url: '/passport/agreement'})}
|
||||
className={'text-blue-600'}>《服务协议及隐私政策》</a>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default Login
|
||||
51
src/pages/index/Menu.tsx
Normal file
51
src/pages/index/Menu.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import Taro from '@tarojs/taro'
|
||||
import {useEffect, useState} from 'react'
|
||||
import {Image} from '@nutui/nutui-react-taro'
|
||||
import {Loading} from '@nutui/nutui-react-taro'
|
||||
import {listCmsNavigation} from "@/api/cms/cmsNavigation"
|
||||
import {CmsNavigation} from "@/api/cms/cmsNavigation/model"
|
||||
|
||||
const Page = () => {
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
const [navItems, setNavItems] = useState<CmsNavigation[]>([])
|
||||
|
||||
const reload = async () => {
|
||||
// 读取栏目
|
||||
const menus = await listCmsNavigation({model: 'links', hide: 0});
|
||||
setNavItems(menus || [])
|
||||
};
|
||||
|
||||
const onNav = (row: CmsNavigation) => {
|
||||
console.log(row, 'eee')
|
||||
Taro.navigateTo({url: `${row.path}`})
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
reload().then(() => {
|
||||
setLoading(false)
|
||||
});
|
||||
}, [])
|
||||
|
||||
return (
|
||||
loading ? (<Loading>加载中</Loading>) :
|
||||
<div className={'p-3'}>
|
||||
<div className={'rounded-2xl'}>
|
||||
<div className={'flex justify-between pb-2 px-1'}>
|
||||
{
|
||||
navItems.map((item, index) => (
|
||||
<div key={index} className={'text-center'} onClick={() => onNav(item)}>
|
||||
<div className={'flex flex-col justify-center items-center'}>
|
||||
<Image src={item.icon} height={36} width={36}/>
|
||||
<div className={'mt-2 text-gray-600'} style={{fontSize: '14px'}}>{item?.title}</div>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Page
|
||||
57
src/pages/index/MySearch.tsx
Normal file
57
src/pages/index/MySearch.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import {Search} from '@nutui/icons-react-taro'
|
||||
import {Button, Input} from '@nutui/nutui-react-taro'
|
||||
import {useState} from "react";
|
||||
import Taro from '@tarojs/taro';
|
||||
function MySearch(props) {
|
||||
const [keywords, setKeywords] = useState<string>('')
|
||||
|
||||
const onKeywords = (keywords: string) => {
|
||||
setKeywords(keywords)
|
||||
}
|
||||
|
||||
const onQuery = () => {
|
||||
if(!keywords){
|
||||
Taro.showToast({
|
||||
title: '请输入关键字',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
props.done(keywords);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className={'z-20 left-0 w-full'}>
|
||||
<div className={'px-2'}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
background: '#fff',
|
||||
padding: '0 7px',
|
||||
borderRadius: '20px'
|
||||
}}
|
||||
>
|
||||
<Search size={18} className={'ml-2 text-gray-400'}/>
|
||||
<Input
|
||||
placeholder="搜索商品"
|
||||
value={keywords}
|
||||
onChange={onKeywords}
|
||||
onConfirm={onQuery}
|
||||
style={{ padding: '9px 8px'}}
|
||||
/>
|
||||
<div
|
||||
className={'flex items-center'}
|
||||
>
|
||||
<Button type="success" style={{background: 'linear-gradient(to bottom, #1cd98a, #24ca94)'}} onClick={onQuery}>
|
||||
搜索
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MySearch;
|
||||
29
src/pages/index/SiteUrl.tsx
Normal file
29
src/pages/index/SiteUrl.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {Input, Button} from '@nutui/nutui-react-taro'
|
||||
import {copyText} from "@/utils/common";
|
||||
import Taro from '@tarojs/taro'
|
||||
|
||||
const SiteUrl = (props: any) => {
|
||||
const [siteUrl, setSiteUrl] = useState<string>('')
|
||||
const reload = () => {
|
||||
if(props.tenantId){
|
||||
setSiteUrl(`https://${props.tenantId}.shoplnk.cn`)
|
||||
}else {
|
||||
setSiteUrl(`https://${Taro.getStorageSync('TenantId')}.shoplnk.cn`)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
reload()
|
||||
}, [props])
|
||||
|
||||
return (
|
||||
<div className={'px-3 mt-1 mb-4'}>
|
||||
<div className={'flex justify-between items-center bg-gray-300 rounded-lg pr-2'}>
|
||||
<Input type="text" value={siteUrl} disabled style={{backgroundColor: '#d1d5db', borderRadius: '8px'}}/>
|
||||
<Button type={'info'} onClick={() => copyText(siteUrl)}>复制</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default SiteUrl
|
||||
38
src/pages/index/chart/DemoLine.tsx
Normal file
38
src/pages/index/chart/DemoLine.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { useRef, useEffect } from 'react'
|
||||
import { View } from '@tarojs/components'
|
||||
import { EChart } from "echarts-taro3-react";
|
||||
import './index.scss'
|
||||
|
||||
export default function Index() {
|
||||
const refBarChart = useRef<any>()
|
||||
const defautOption = {
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [120, 200, 150, 80, 70, 110, 130],
|
||||
type: "line",
|
||||
showBackground: true,
|
||||
backgroundStyle: {
|
||||
color: "rgba(220, 220, 220, 0.8)",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
useEffect(() => {
|
||||
if(refBarChart.current) {
|
||||
refBarChart.current?.refresh(defautOption);
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<View className='index'>
|
||||
<EChart ref={refBarChart} canvasId='line-canvas' />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
7
src/pages/index/chart/index.scss
Normal file
7
src/pages/index/chart/index.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
.index {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #F3F3F3;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100%;
|
||||
}
|
||||
5
src/pages/index/index.config.ts
Normal file
5
src/pages/index/index.config.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: 'shopLnk.cn - 数灵云店',
|
||||
navigationBarTextStyle: 'black',
|
||||
navigationStyle: 'custom'
|
||||
})
|
||||
20
src/pages/index/index.scss
Normal file
20
src/pages/index/index.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
page {
|
||||
//background: url('https://oss.wsdns.cn/20250621/33ca4ca532e647bc918a59d01f5d88a9.jpg?x-oss-process=image/resize,m_fixed,w_2000/quality,Q_90') no-repeat top center;
|
||||
//background-size: 100%;
|
||||
background: linear-gradient(to bottom, #e9fff2, #ffffff);
|
||||
}
|
||||
|
||||
.buy-btn{
|
||||
height: 70px;
|
||||
background: linear-gradient(to bottom, #1cd98a, #24ca94);
|
||||
border-radius: 100px;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
.cart-icon{
|
||||
background: linear-gradient(to bottom, #bbe094, #4ee265);
|
||||
border-radius: 100px 0 0 100px;
|
||||
height: 70px;
|
||||
}
|
||||
}
|
||||
116
src/pages/index/index.tsx
Normal file
116
src/pages/index/index.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
import Header from './Header';
|
||||
import MySearch from "./MySearch";
|
||||
import BestSellers from './BestSellers';
|
||||
import Taro from '@tarojs/taro';
|
||||
import {useShareAppMessage, useShareTimeline} from "@tarojs/taro"
|
||||
import {useEffect} from "react";
|
||||
import {getSiteInfo} from "@/api/layout";
|
||||
import Menu from "./Menu";
|
||||
import Banner from "./Banner";
|
||||
import './index.scss'
|
||||
|
||||
function Home() {
|
||||
|
||||
useShareTimeline(() => {
|
||||
return {
|
||||
title: '云上商店 - 网宿软件',
|
||||
path: `/pages/index/index`
|
||||
};
|
||||
});
|
||||
|
||||
useShareAppMessage(() => {
|
||||
return {
|
||||
title: '云上商店 - 网宿软件',
|
||||
path: `/pages/index/index`,
|
||||
success: function (res) {
|
||||
console.log('分享成功', res);
|
||||
},
|
||||
fail: function (res) {
|
||||
console.log('分享失败', res);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// const reloadMore = async () => {
|
||||
// setPage(page + 1)
|
||||
// }
|
||||
|
||||
const showAuthModal = () => {
|
||||
Taro.showModal({
|
||||
title: '授权提示',
|
||||
content: '需要获取您的用户信息',
|
||||
confirmText: '去授权',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 用户点击确认,打开授权设置页面
|
||||
openSetting();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const openSetting = () => {
|
||||
// Taro.openSetting:调起客户端小程序设置界面,返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限。
|
||||
Taro.openSetting({
|
||||
success: (res) => {
|
||||
if (res.authSetting['scope.userInfo']) {
|
||||
// 用户授权成功,可以获取用户信息
|
||||
reload();
|
||||
} else {
|
||||
// 用户拒绝授权,提示授权失败
|
||||
Taro.showToast({
|
||||
title: '授权失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const reload = () => {
|
||||
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// 获取站点信息
|
||||
getSiteInfo().then(() => {
|
||||
|
||||
})
|
||||
// Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
|
||||
Taro.getSetting({
|
||||
success: (res) => {
|
||||
if (res.authSetting['scope.userInfo']) {
|
||||
// 用户已经授权过,可以直接获取用户信息
|
||||
console.log('用户已经授权过,可以直接获取用户信息')
|
||||
reload();
|
||||
} else {
|
||||
// 用户未授权,需要弹出授权窗口
|
||||
console.log('用户未授权,需要弹出授权窗口')
|
||||
showAuthModal();
|
||||
}
|
||||
}
|
||||
});
|
||||
// 获取用户信息
|
||||
Taro.getUserInfo({
|
||||
success: (res) => {
|
||||
const avatar = res.userInfo.avatarUrl;
|
||||
console.log(avatar,'avatarUrl')
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header/>
|
||||
<MySearch done={reload}/>
|
||||
<div className={'flex flex-col mt-3'}>
|
||||
<Banner />
|
||||
<Menu />
|
||||
<BestSellers/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Home
|
||||
10
src/pages/index/login.scss
Normal file
10
src/pages/index/login.scss
Normal file
@@ -0,0 +1,10 @@
|
||||
// 微信授权按钮的特殊样式
|
||||
button[open-type="getPhoneNumber"] {
|
||||
width: 100%;
|
||||
padding: 8px 0 !important;
|
||||
height: 80px;
|
||||
color: #ffffff !important;
|
||||
margin: 0 !important;
|
||||
border: none !important;
|
||||
border-radius: 50px !important;
|
||||
}
|
||||
5
src/pages/kefu/kefu.config.ts
Normal file
5
src/pages/kefu/kefu.config.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '商品列表',
|
||||
navigationBarTextStyle: 'black',
|
||||
navigationStyle: 'custom'
|
||||
})
|
||||
67
src/pages/kefu/kefu.tsx
Normal file
67
src/pages/kefu/kefu.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import {useEffect, useState} from "react"; // 添加 useCallback 引入
|
||||
import Taro, {useShareAppMessage, useShareTimeline} from '@tarojs/taro';
|
||||
import {Space, NavBar} from '@nutui/nutui-react-taro'
|
||||
import {Search, Received, Scan} from '@nutui/icons-react-taro'
|
||||
import GoodsList from "@/components/GoodsList";
|
||||
|
||||
function Kefu() {
|
||||
const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
||||
|
||||
useShareTimeline(() => {
|
||||
return {
|
||||
title: '注册即可开通 - webSoft云应用'
|
||||
};
|
||||
});
|
||||
|
||||
useShareAppMessage(() => {
|
||||
return {
|
||||
title: '注册即可开通 - webSoft云应用',
|
||||
success: function (res) {
|
||||
console.log('分享成功', res);
|
||||
},
|
||||
fail: function (res) {
|
||||
console.log('分享失败', res);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
Taro.getSystemInfo({
|
||||
success: (res) => {
|
||||
setStatusBarHeight(res.statusBarHeight)
|
||||
},
|
||||
})
|
||||
// 设置导航栏背景色(含状态栏)
|
||||
Taro.setNavigationBarColor({
|
||||
backgroundColor: '#ffffff', // 状态栏+导航栏背景色
|
||||
frontColor: 'black', // 状态栏文字颜色(仅支持 black/white)
|
||||
});
|
||||
}, []); // 新增: 添加滚动事件监听
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavBar
|
||||
fixed={true}
|
||||
style={{marginTop: `${statusBarHeight}px`}}
|
||||
onBackClick={() => {
|
||||
}}
|
||||
left={
|
||||
<>
|
||||
<div className={'flex justify-between items-center w-full'}>
|
||||
<Space>
|
||||
<Search size={18} className={'mx-1'}/>
|
||||
<Received size={18} className={'mx-1'}/>
|
||||
<Scan size={18} className={'mx-1'}/>
|
||||
</Space>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<span>商品</span>
|
||||
</NavBar>
|
||||
<GoodsList/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Kefu;
|
||||
5
src/pages/order/order.config.ts
Normal file
5
src/pages/order/order.config.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '订单列表',
|
||||
navigationBarTextStyle: 'black',
|
||||
navigationStyle: 'custom'
|
||||
})
|
||||
4
src/pages/order/order.scss
Normal file
4
src/pages/order/order.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
page {
|
||||
background: linear-gradient(to bottom, #e9fff2, #f9fafb);
|
||||
background-size: 100%;
|
||||
}
|
||||
53
src/pages/order/order.tsx
Normal file
53
src/pages/order/order.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import {useEffect, useState} from "react"; // 添加 useCallback 引入
|
||||
import Taro from '@tarojs/taro';
|
||||
import {NavBar, Space} from '@nutui/nutui-react-taro'
|
||||
import {Search} from '@nutui/icons-react-taro'
|
||||
import OrderList from "@/components/OrderList";
|
||||
import './order.scss'
|
||||
function Order() {
|
||||
const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
||||
|
||||
useEffect(() => {
|
||||
Taro.getSystemInfo({
|
||||
success: (res) => {
|
||||
setStatusBarHeight(res.statusBarHeight)
|
||||
},
|
||||
})
|
||||
// 设置导航栏背景色(含状态栏)
|
||||
Taro.setNavigationBarColor({
|
||||
backgroundColor: '#ffffff', // 状态栏+导航栏背景色
|
||||
frontColor: 'black', // 状态栏文字颜色(仅支持 black/white)
|
||||
});
|
||||
}, []); // 新增: 添加滚动事件监听
|
||||
|
||||
return (
|
||||
<>
|
||||
<NavBar
|
||||
fixed={true}
|
||||
style={{marginTop: `${statusBarHeight}px`, backgroundColor: 'transparent'}}
|
||||
onBackClick={() => {
|
||||
}}
|
||||
left={
|
||||
<>
|
||||
<div className={'flex justify-between items-center w-full'}>
|
||||
<Space>
|
||||
<Search size={18} className={'mx-1'}/>
|
||||
{/*<Filter size={18} className={'mx-1'}/>*/}
|
||||
</Space>
|
||||
</div>
|
||||
{/*<SearchBar shape="round" maxLength={5} style={{paddingLeft: '1px'}}/>*/}
|
||||
{/*<div className={'flex flex-col text-center justify-center items-center'}>*/}
|
||||
{/* <Filter size={14}/>*/}
|
||||
{/* <div className={'text-xs text-gray-600 whitespace-nowrap'}>筛选</div>*/}
|
||||
{/*</div>*/}
|
||||
</>
|
||||
}
|
||||
>
|
||||
<span>订单</span>
|
||||
</NavBar>
|
||||
<OrderList/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Order;
|
||||
211
src/pages/user/components/OrderIcon.tsx
Normal file
211
src/pages/user/components/OrderIcon.tsx
Normal file
@@ -0,0 +1,211 @@
|
||||
import {useEffect, useState} from 'react'
|
||||
import {navigateTo} from '@tarojs/taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {Button} from '@tarojs/components';
|
||||
import {Image} from '@nutui/nutui-react-taro'
|
||||
import {getUserInfo, getWxOpenId} from "@/api/layout";
|
||||
import {TenantId} from "@/utils/config";
|
||||
import {User} from "@/api/system/user/model";
|
||||
// import News from "./News";
|
||||
import {myPageBszxBm} from "@/api/bszx/bszxBm";
|
||||
import {listCmsNavigation} from "@/api/cms/cmsNavigation";
|
||||
|
||||
const OrderIcon = () => {
|
||||
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [isLogin, setIsLogin] = useState<boolean>(false)
|
||||
const [userInfo, setUserInfo] = useState<User>()
|
||||
const [bmLogs, setBmLogs] = useState<any>()
|
||||
const [navItems, setNavItems] = useState<any>([])
|
||||
|
||||
/* 获取用户手机号 */
|
||||
const handleGetPhoneNumber = ({detail}) => {
|
||||
const {code, encryptedData, iv} = detail
|
||||
Taro.login({
|
||||
success: function () {
|
||||
if (code) {
|
||||
Taro.request({
|
||||
url: 'https://server.gxwebsoft.com/api/wx-login/loginByMpWxPhone',
|
||||
method: 'POST',
|
||||
data: {
|
||||
code,
|
||||
encryptedData,
|
||||
iv,
|
||||
notVerifyPhone: true,
|
||||
refereeId: 0,
|
||||
sceneType: 'save_referee',
|
||||
tenantId: TenantId
|
||||
},
|
||||
header: {
|
||||
'content-type': 'application/json',
|
||||
TenantId
|
||||
},
|
||||
success: function (res) {
|
||||
Taro.setStorageSync('access_token', res.data.data.access_token)
|
||||
Taro.setStorageSync('UserId', res.data.data.user.userId)
|
||||
setUserInfo(res.data.data.user)
|
||||
Taro.setStorageSync('Phone', res.data.data.user.phone)
|
||||
setIsLogin(true)
|
||||
Taro.showToast({
|
||||
title: '登录成功',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('登录失败!')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const onLogin = (item: any, index: number) => {
|
||||
if(!isLogin){
|
||||
return navigateTo({url: `/pages/category/category?id=${item.navigationId}`})
|
||||
}else {
|
||||
// 报名链接
|
||||
if(index == 0){
|
||||
console.log(bmLogs,'bmLogs')
|
||||
if(bmLogs && bmLogs.length > 0){
|
||||
return navigateTo({url: `/bszx/bm-cert/bm-cert?id=${bmLogs[0].id}`})
|
||||
}else {
|
||||
navigateTo({url: `/user/profile/profile`})
|
||||
}
|
||||
}
|
||||
// 善款明细
|
||||
if(item.navigationId == 4119){
|
||||
return navigateTo({url: `/bszx/pay-record/pay-record`})
|
||||
}
|
||||
return navigateTo({url: `/pages/category/category?id=${item.navigationId}`})
|
||||
}
|
||||
}
|
||||
|
||||
const reload = () => {
|
||||
// 读取栏目
|
||||
listCmsNavigation({parentId: 2828,hide: 0}).then(res => {
|
||||
console.log(res,'9999')
|
||||
setNavItems(res);
|
||||
})
|
||||
Taro.getUserInfo({
|
||||
success: (res) => {
|
||||
const avatar = res.userInfo.avatarUrl;
|
||||
setUserInfo({
|
||||
avatar,
|
||||
nickname: res.userInfo.nickName,
|
||||
sexName: res.userInfo.gender == 1 ? '男' : '女'
|
||||
})
|
||||
getUserInfo().then((data) => {
|
||||
if (data) {
|
||||
setUserInfo(data)
|
||||
setIsLogin(true);
|
||||
console.log(userInfo, 'userInfo...')
|
||||
Taro.setStorageSync('UserId', data.userId)
|
||||
// 获取openId
|
||||
if (!data.openid) {
|
||||
Taro.login({
|
||||
success: (res) => {
|
||||
getWxOpenId({code: res.code}).then(() => {
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}).catch(() => {
|
||||
console.log('未登录')
|
||||
});
|
||||
}
|
||||
});
|
||||
// 报名日志
|
||||
myPageBszxBm({limit: 1}).then(res => {
|
||||
if (res.list) {
|
||||
setBmLogs(res.list);
|
||||
}
|
||||
})
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const showAuthModal = () => {
|
||||
Taro.showModal({
|
||||
title: '授权提示',
|
||||
content: '需要获取您的用户信息',
|
||||
confirmText: '去授权',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 用户点击确认,打开授权设置页面
|
||||
openSetting();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const openSetting = () => {
|
||||
// Taro.openSetting:调起客户端小程序设置界面,返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限。
|
||||
Taro.openSetting({
|
||||
success: (res) => {
|
||||
if (res.authSetting['scope.userInfo']) {
|
||||
// 用户授权成功,可以获取用户信息
|
||||
reload();
|
||||
} else {
|
||||
// 用户拒绝授权,提示授权失败
|
||||
Taro.showToast({
|
||||
title: '授权失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
Taro.getSetting({
|
||||
success: (res) => {
|
||||
if (res.authSetting['scope.userInfo']) {
|
||||
// 用户已经授权过,可以直接获取用户信息
|
||||
console.log('用户已经授权过,可以直接获取用户信息')
|
||||
reload();
|
||||
} else {
|
||||
// 用户未授权,需要弹出授权窗口
|
||||
console.log('用户未授权,需要弹出授权窗口')
|
||||
showAuthModal();
|
||||
}
|
||||
}
|
||||
});
|
||||
reload();
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={'my-3'}>
|
||||
<div className={'pt-4 bg-yellow-50 rounded-2xl'}
|
||||
style={{background: 'linear-gradient(to bottom, #ffffff, #ffffcc)'}}>
|
||||
<div className={'flex justify-between pb-2 px-1'}>
|
||||
{
|
||||
navItems.map((item, index) => (
|
||||
<div key={index} className={'text-center'}>
|
||||
{
|
||||
isLogin && !loading ?
|
||||
<div className={'flex flex-col justify-center items-center'} onClick={() => {
|
||||
onLogin(item, index)
|
||||
}}>
|
||||
<Image src={item.icon} height={28} width={28}/>
|
||||
<div className={'mt-2'} style={{fontSize: '15px'}}>{item?.title}</div>
|
||||
</div>
|
||||
:
|
||||
<Button className={'text-white'} open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
|
||||
<div className={'flex flex-col justify-center items-center'}>
|
||||
<Image src={item.icon} height={28} width={28}/>
|
||||
<div className={'mt-2 text-gray-700'} style={{fontSize: '15px'}}>{item?.title}</div>
|
||||
</div>
|
||||
</Button>
|
||||
}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{/*<image src={'https://oss.wsdns.cn/20250224/18a2f3b807c94aac8a67af34e95534d6.jpeg'} className={'book'}>倡议书</image>*/}
|
||||
{/*<News id={categoryId}/>*/}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default OrderIcon
|
||||
209
src/pages/user/components/UserCard.tsx
Normal file
209
src/pages/user/components/UserCard.tsx
Normal file
@@ -0,0 +1,209 @@
|
||||
import {Button} from '@nutui/nutui-react-taro'
|
||||
import {Avatar, Tag} from '@nutui/nutui-react-taro'
|
||||
import {getUserInfo, getWxOpenId} from '@/api/layout';
|
||||
import Taro from '@tarojs/taro';
|
||||
import {useEffect, useState} from "react";
|
||||
import {User} from "@/api/system/user/model";
|
||||
import navTo from "@/utils/common";
|
||||
import {TenantId} from "@/utils/config";
|
||||
|
||||
function UserCard() {
|
||||
const [IsLogin, setIsLogin] = useState<boolean>(false)
|
||||
const [userInfo, setUserInfo] = useState<User>()
|
||||
const [roleName, setRoleName] = useState<string>('注册用户')
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
// Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
|
||||
Taro.getSetting({
|
||||
success: (res) => {
|
||||
if (res.authSetting['scope.userInfo']) {
|
||||
// 用户已经授权过,可以直接获取用户信息
|
||||
console.log('用户已经授权过,可以直接获取用户信息')
|
||||
reload();
|
||||
} else {
|
||||
// 用户未授权,需要弹出授权窗口
|
||||
console.log('用户未授权,需要弹出授权窗口')
|
||||
showAuthModal();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const reload = () => {
|
||||
Taro.getUserInfo({
|
||||
success: (res) => {
|
||||
const avatar = res.userInfo.avatarUrl;
|
||||
setUserInfo({
|
||||
avatar,
|
||||
nickname: res.userInfo.nickName,
|
||||
sexName: res.userInfo.gender == 1 ? '男' : '女'
|
||||
})
|
||||
getUserInfo().then((data) => {
|
||||
if (data) {
|
||||
setUserInfo(data)
|
||||
setIsLogin(true);
|
||||
Taro.setStorageSync('UserId', data.userId)
|
||||
// 获取openId
|
||||
if (!data.openid) {
|
||||
Taro.login({
|
||||
success: (res) => {
|
||||
getWxOpenId({code: res.code}).then(() => {
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// 判断身份
|
||||
const roleName = Taro.getStorageSync('RoleName');
|
||||
if(roleName){
|
||||
setRoleName(roleName)
|
||||
}
|
||||
}
|
||||
}).catch(() => {
|
||||
console.log('未登录')
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const showAuthModal = () => {
|
||||
Taro.showModal({
|
||||
title: '授权提示',
|
||||
content: '需要获取您的用户信息',
|
||||
confirmText: '去授权',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 用户点击确认,打开授权设置页面
|
||||
openSetting();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const openSetting = () => {
|
||||
// Taro.openSetting:调起客户端小程序设置界面,返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限。
|
||||
Taro.openSetting({
|
||||
success: (res) => {
|
||||
if (res.authSetting['scope.userInfo']) {
|
||||
// 用户授权成功,可以获取用户信息
|
||||
reload();
|
||||
} else {
|
||||
// 用户拒绝授权,提示授权失败
|
||||
Taro.showToast({
|
||||
title: '授权失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/* 获取用户手机号 */
|
||||
const handleGetPhoneNumber = ({detail}) => {
|
||||
const {code, encryptedData, iv} = detail
|
||||
Taro.login({
|
||||
success: function () {
|
||||
if (code) {
|
||||
Taro.request({
|
||||
url: 'https://server.gxwebsoft.com/api/wx-login/loginByMpWxPhone',
|
||||
method: 'POST',
|
||||
data: {
|
||||
code,
|
||||
encryptedData,
|
||||
iv,
|
||||
notVerifyPhone: true,
|
||||
refereeId: 0,
|
||||
sceneType: 'save_referee',
|
||||
tenantId: TenantId
|
||||
},
|
||||
header: {
|
||||
'content-type': 'application/json',
|
||||
TenantId
|
||||
},
|
||||
success: function (res) {
|
||||
if(res.data.code == 1){
|
||||
Taro.showToast({
|
||||
title: res.data.message,
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
})
|
||||
return false;
|
||||
}
|
||||
// 登录成功
|
||||
Taro.setStorageSync('access_token', res.data.data.access_token)
|
||||
Taro.setStorageSync('UserId', res.data.data.user.userId)
|
||||
setUserInfo(res.data.data.user)
|
||||
setIsLogin(true)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log('登录失败!')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={'p-4'}>
|
||||
<div
|
||||
className={'user-card w-full flex flex-col justify-around rounded-xl shadow-sm'}
|
||||
style={{
|
||||
background: 'linear-gradient(to bottom, #ffffff, #ffffff)', // 这种情况建议使用类名来控制样式(引入外联样式)
|
||||
// width: '720rpx',
|
||||
// margin: '10px auto 0px auto',
|
||||
height: '180px',
|
||||
// borderRadius: '22px 22px 0 0',
|
||||
}}
|
||||
>
|
||||
<div className={'user-card-header flex w-full justify-between items-center pt-4'}>
|
||||
<div className={'flex items-center mx-4'}>
|
||||
{
|
||||
IsLogin ? (
|
||||
<Avatar size="large" src={userInfo?.avatar} shape="round"/>
|
||||
) : (
|
||||
<Button className={'text-black'} open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
|
||||
<Avatar size="large" src={userInfo?.avatar} shape="round"/>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
<div className={'user-info flex flex-col px-2'}>
|
||||
<div className={'py-1 text-black font-bold'}>{IsLogin ? userInfo?.mobile : '请点击头像登录'}</div>
|
||||
{IsLogin ? (
|
||||
<div className={'grade text-xs py-1'}>
|
||||
<Tag type="success" round>
|
||||
<div className={'p-1'}>{roleName || '注册用户'}</div>
|
||||
</Tag>
|
||||
</div>
|
||||
) : ''}
|
||||
</div>
|
||||
</div>
|
||||
<div className={'mx-4 text-sm px-3 py-1 text-black border-gray-400 border-solid border-2 rounded-3xl'}
|
||||
onClick={() => navTo('/user/profile/profile', true)}>
|
||||
{'个人资料'}
|
||||
</div>
|
||||
</div>
|
||||
<div className={'flex justify-around mt-5'}>
|
||||
<div className={'item flex justify-center flex-col items-center'}>
|
||||
<span className={'text-sm text-gray-500'}>余额</span>
|
||||
<span className={'text-xl'}>¥ 0.00</span>
|
||||
</div>
|
||||
<div className={'item flex justify-center flex-col items-center'}>
|
||||
<span className={'text-sm text-gray-500'}>优惠券</span>
|
||||
<span className={'text-xl'}>0</span>
|
||||
</div>
|
||||
<div className={'item flex justify-center flex-col items-center'}>
|
||||
<span className={'text-sm text-gray-500'}>积分</span>
|
||||
<span className={'text-xl'}>100</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default UserCard;
|
||||
202
src/pages/user/components/UserCell.tsx
Normal file
202
src/pages/user/components/UserCell.tsx
Normal file
@@ -0,0 +1,202 @@
|
||||
import {Cell, InfiniteLoading} from '@nutui/nutui-react-taro'
|
||||
import navTo from "@/utils/common";
|
||||
import UserFooter from "./UserFooter";
|
||||
import Taro from '@tarojs/taro'
|
||||
import {ArrowRight, ShieldCheck, Truck, LogisticsError, Presentation, Coupon, PickedUp} from '@nutui/icons-react-taro'
|
||||
import {CSSProperties} from "react";
|
||||
|
||||
const UserCell = () => {
|
||||
const InfiniteUlStyle: CSSProperties = {
|
||||
height: '88vh',
|
||||
padding: '16px',
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
}
|
||||
const onLogout = () => {
|
||||
Taro.showModal({
|
||||
title: '提示',
|
||||
content: '确定要退出登录吗?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
Taro.removeStorageSync('access_token')
|
||||
Taro.removeStorageSync('TenantId')
|
||||
Taro.removeStorageSync('UserId')
|
||||
Taro.removeStorageSync('userInfo')
|
||||
Taro.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={'px-4'}>
|
||||
{/*<Cell*/}
|
||||
{/* className="nutui-cell-clickable"*/}
|
||||
{/* title={*/}
|
||||
{/* <div style={{display: 'inline-flex', alignItems: 'center'}}>*/}
|
||||
{/* <Truck size={16}/>*/}
|
||||
{/* <span className={'pl-3 text-sm'}>开通会员</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* }*/}
|
||||
{/*/>*/}
|
||||
<Cell.Group divider={true} description={
|
||||
<div style={{display: 'inline-flex', alignItems: 'center'}}>
|
||||
<span style={{marginTop: '12px'}}>我的服务</span>
|
||||
</div>
|
||||
}>
|
||||
<Cell
|
||||
className="nutui-cell-clickable"
|
||||
title={
|
||||
<div style={{display: 'inline-flex', alignItems: 'center'}}>
|
||||
<Truck size={16}/>
|
||||
<span className={'pl-3 text-sm'}>我的券包</span>
|
||||
</div>
|
||||
}
|
||||
align="center"
|
||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||
/>
|
||||
<Cell
|
||||
className="nutui-cell-clickable"
|
||||
title={
|
||||
<div style={{display: 'inline-flex', alignItems: 'center'}}>
|
||||
<LogisticsError size={16}/>
|
||||
<span className={'pl-3 text-sm'}>我的钱包</span>
|
||||
</div>
|
||||
}
|
||||
align="center"
|
||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||
/>
|
||||
<Cell
|
||||
className="nutui-cell-clickable"
|
||||
title={
|
||||
<div style={{display: 'inline-flex', alignItems: 'center'}}>
|
||||
<LogisticsError size={16}/>
|
||||
<span className={'pl-3 text-sm'}>收货地址</span>
|
||||
</div>
|
||||
}
|
||||
align="center"
|
||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||
/>
|
||||
<Cell
|
||||
className="nutui-cell-clickable"
|
||||
title={
|
||||
<div style={{display: 'inline-flex', alignItems: 'center'}}>
|
||||
<ShieldCheck size={16}/>
|
||||
<span className={'pl-3 text-sm'}>实名认证</span>
|
||||
</div>
|
||||
}
|
||||
align="center"
|
||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||
onClick={() => {
|
||||
navTo('/user/userVerify/index', true)
|
||||
}}
|
||||
/>
|
||||
</Cell.Group>
|
||||
{/*<Cell.Group divider={true} description={*/}
|
||||
{/* <div style={{display: 'inline-flex', alignItems: 'center'}}>*/}
|
||||
{/* <span style={{marginTop: '12px'}}>管理</span>*/}
|
||||
{/* </div>*/}
|
||||
{/*}>*/}
|
||||
{/* <Cell*/}
|
||||
{/* className="nutui-cell-clickable"*/}
|
||||
{/* title={*/}
|
||||
{/* <div style={{display: 'inline-flex', alignItems: 'center'}}>*/}
|
||||
{/* <Presentation size={18}/>*/}
|
||||
{/* <span style={{marginLeft: '5px'}}>分析</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* }*/}
|
||||
{/* align="center"*/}
|
||||
{/* extra={<ArrowRight color="#cccccc" size={18}/>}*/}
|
||||
{/* onClick={() => {*/}
|
||||
{/* navTo('/bszx/bm-cert/bm-cert', true)*/}
|
||||
{/* }}*/}
|
||||
{/* />*/}
|
||||
{/* <Cell*/}
|
||||
{/* className="nutui-cell-clickable"*/}
|
||||
{/* title={*/}
|
||||
{/* <div style={{display: 'inline-flex', alignItems: 'center'}}>*/}
|
||||
{/* <PickedUp size={18}/>*/}
|
||||
{/* <span style={{marginLeft: '5px'}}>客户</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* }*/}
|
||||
{/* align="center"*/}
|
||||
{/* extra={<ArrowRight color="#cccccc" size={18}/>}*/}
|
||||
{/* onClick={() => {*/}
|
||||
{/* navTo('/bszx/pay-log/pay-log', true)*/}
|
||||
{/* }}*/}
|
||||
{/* />*/}
|
||||
{/* <Cell*/}
|
||||
{/* className="nutui-cell-clickable"*/}
|
||||
{/* title={*/}
|
||||
{/* <div style={{display: 'inline-flex', alignItems: 'center'}}>*/}
|
||||
{/* <Coupon size={18}/>*/}
|
||||
{/* <span style={{marginLeft: '5px'}}>折扣</span>*/}
|
||||
{/* </div>*/}
|
||||
{/* }*/}
|
||||
{/* align="center"*/}
|
||||
{/* extra={<ArrowRight color="#cccccc" size={18}/>}*/}
|
||||
{/* onClick={() => {*/}
|
||||
{/* navTo('/user/profile/profile', true)*/}
|
||||
{/* }}*/}
|
||||
{/* />*/}
|
||||
{/*</Cell.Group>*/}
|
||||
{/*<Cell.Group divider={true} description={*/}
|
||||
{/* <div style={{display: 'inline-flex', alignItems: 'center'}}>*/}
|
||||
{/* <span style={{marginTop: '12px'}}>设置与帮助</span>*/}
|
||||
{/* </div>*/}
|
||||
{/*}>*/}
|
||||
{/* <Cell*/}
|
||||
{/* className="nutui-cell-clickable"*/}
|
||||
{/* title="店铺设置"*/}
|
||||
{/* align="center"*/}
|
||||
{/* extra={<ArrowRight color="#cccccc" size={18}/>}*/}
|
||||
{/* onClick={() => Taro.navigateTo({url: '/website/modify'})}*/}
|
||||
{/* />*/}
|
||||
{/* <Cell*/}
|
||||
{/* className="nutui-cell-clickable"*/}
|
||||
{/* title="帮助中心"*/}
|
||||
{/* align="center"*/}
|
||||
{/* extra={<ArrowRight color="#cccccc" size={18}/>}*/}
|
||||
{/* onClick={() => {*/}
|
||||
{/* navTo('/user/profile/profile', true)*/}
|
||||
{/* }}*/}
|
||||
{/* />*/}
|
||||
{/* <Cell*/}
|
||||
{/* className="nutui-cell-clickable"*/}
|
||||
{/* title="问题反馈"*/}
|
||||
{/* align="center"*/}
|
||||
{/* extra={<ArrowRight color="#cccccc" size={18}/>}*/}
|
||||
{/* onClick={() => {*/}
|
||||
{/* navTo('/user/profile/profile', true)*/}
|
||||
{/* }}*/}
|
||||
{/* />*/}
|
||||
{/*</Cell.Group>*/}
|
||||
<Cell.Group divider={true} description={
|
||||
<div style={{display: 'inline-flex', alignItems: 'center'}}>
|
||||
<span style={{marginTop: '12px'}}>账号管理</span>
|
||||
</div>
|
||||
}>
|
||||
<Cell
|
||||
className="nutui-cell-clickable"
|
||||
title="账号安全"
|
||||
align="center"
|
||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||
onClick={() => navTo('/user/profile/profile', true)}
|
||||
/>
|
||||
<Cell
|
||||
className="nutui-cell-clickable"
|
||||
title="退出登录"
|
||||
align="center"
|
||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||
onClick={onLogout}
|
||||
/>
|
||||
</Cell.Group>
|
||||
</div>
|
||||
<UserFooter/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default UserCell
|
||||
102
src/pages/user/components/UserFooter.tsx
Normal file
102
src/pages/user/components/UserFooter.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import {loginBySms} from "@/api/passport/login";
|
||||
import {useState} from "react";
|
||||
import Taro from '@tarojs/taro'
|
||||
import {Popup} from '@nutui/nutui-react-taro'
|
||||
import {UserParam} from "@/api/system/user/model";
|
||||
import {Button} from '@nutui/nutui-react-taro'
|
||||
import {Form, Input} from '@nutui/nutui-react-taro'
|
||||
import {Copyright, Version} from "@/utils/config";
|
||||
const UserFooter = () => {
|
||||
const [openLoginByPhone, setOpenLoginByPhone] = useState(false)
|
||||
const [clickNum, setClickNum] = useState<number>(0)
|
||||
const [FormData, setFormData] = useState<UserParam>(
|
||||
{
|
||||
phone: undefined,
|
||||
password: undefined
|
||||
}
|
||||
)
|
||||
|
||||
const onLoginByPhone = () => {
|
||||
setFormData({})
|
||||
setClickNum(clickNum + 1);
|
||||
if (clickNum > 10) {
|
||||
setOpenLoginByPhone(true);
|
||||
}
|
||||
}
|
||||
|
||||
const closeLoginByPhone = () => {
|
||||
setClickNum(0)
|
||||
setOpenLoginByPhone(false)
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitByPhone = (values: any) => {
|
||||
loginBySms({
|
||||
phone: values.phone,
|
||||
code: values.code
|
||||
}).then(() => {
|
||||
setOpenLoginByPhone(false);
|
||||
setTimeout(() => {
|
||||
Taro.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
},1000)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={'text-center bg-gray-50 py-4 w-full text-gray-300'} onClick={onLoginByPhone}>
|
||||
<div className={'text-xs text-gray-400 py-1'}>当前版本:{Version}</div>
|
||||
<div className={'text-xs text-gray-400 py-1'}>Copyright © { new Date().getFullYear() } {Copyright}</div>
|
||||
</div>
|
||||
|
||||
<Popup
|
||||
style={{width: '350px', padding: '10px'}}
|
||||
visible={openLoginByPhone}
|
||||
closeOnOverlayClick={false}
|
||||
closeable={true}
|
||||
onClose={closeLoginByPhone}
|
||||
>
|
||||
<Form
|
||||
style={{width: '350px',padding: '10px'}}
|
||||
divider
|
||||
initialValues={FormData}
|
||||
labelPosition="left"
|
||||
onFinish={(values) => submitByPhone(values)}
|
||||
footer={
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
width: '100%'
|
||||
}}
|
||||
>
|
||||
<Button nativeType="submit" block style={{backgroundColor: '#000000',color: '#ffffff'}}>
|
||||
提交
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Form.Item
|
||||
label={'手机号码'}
|
||||
name="phone"
|
||||
required
|
||||
rules={[{message: '手机号码'}]}
|
||||
>
|
||||
<Input placeholder="请输入手机号码" maxLength={11} type="text"/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={'短信验证码'}
|
||||
name="code"
|
||||
required
|
||||
rules={[{message: '短信验证码'}]}
|
||||
>
|
||||
<Input placeholder="请输入短信验证码" maxLength={6} type="text"/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Popup>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default UserFooter
|
||||
5
src/pages/user/user.config.ts
Normal file
5
src/pages/user/user.config.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: '我的',
|
||||
navigationStyle: 'custom',
|
||||
navigationBarBackgroundColor: '#e9fff2'
|
||||
})
|
||||
8
src/pages/user/user.scss
Normal file
8
src/pages/user/user.scss
Normal file
@@ -0,0 +1,8 @@
|
||||
page {
|
||||
background: linear-gradient(to bottom, #e9fff2, #f9fafb);
|
||||
background-size: 100%;
|
||||
}
|
||||
.header-bg{
|
||||
background: url('https://oss.wsdns.cn/20250621/edb5d4da976b4d97ba185cb7077d2858.jpg') no-repeat top center;
|
||||
background-size: 100%;
|
||||
}
|
||||
19
src/pages/user/user.tsx
Normal file
19
src/pages/user/user.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import {useEffect} from 'react'
|
||||
import UserCard from "./components/UserCard";
|
||||
import UserCell from "./components/UserCell";
|
||||
import './user.scss'
|
||||
function User() {
|
||||
|
||||
useEffect(() => {
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<div className={'w-full header-bg pt-36'}>
|
||||
<UserCard />
|
||||
<UserCell />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default User
|
||||
Reference in New Issue
Block a user