parent
7947e62663
commit
586a1ba696
@ -1 +1,2 @@ |
||||
TARO_APP_API=https://playedu.yaojiankang.top |
||||
TARO_APP_LGOIN=false |
||||
|
@ -0,0 +1,39 @@ |
||||
.lineChart { |
||||
display: flex; |
||||
align-items: flex-end; |
||||
justify-content: left; |
||||
flex-wrap: nowrap; |
||||
height: 400px; |
||||
} |
||||
|
||||
.columnBox { |
||||
display: flex; |
||||
flex-direction: column; |
||||
align-items: center; |
||||
} |
||||
|
||||
.column { |
||||
width: 30rpx; |
||||
background: linear-gradient(180deg, #03D9B3 0%, #05BF88 100%); |
||||
border-radius: 30rpx; |
||||
margin-bottom: 20rpx; |
||||
overflow: hidden; |
||||
animation: rise 300ms ease-in-out forwards; |
||||
max-height: 0; |
||||
} |
||||
|
||||
.line { |
||||
width: 1rpx; |
||||
background: #ddd; |
||||
height: 100%; |
||||
margin-bottom: 10px; |
||||
} |
||||
|
||||
@keyframes rise { |
||||
from { |
||||
max-height: 0; |
||||
} |
||||
to { |
||||
max-height: 300rpx; |
||||
} |
||||
} |
@ -0,0 +1,43 @@ |
||||
import {ScrollView, View} from "@tarojs/components"; |
||||
import {FC, useEffect, useState} from "react"; |
||||
import style from './lineChart.module.scss' |
||||
|
||||
export interface lineData { |
||||
time: string |
||||
value: number |
||||
} |
||||
|
||||
interface Props { |
||||
data: lineData[] |
||||
} |
||||
|
||||
const height = 180 |
||||
const LineChart: FC<Props> = ({data}) => { |
||||
const [maxHeight, setMaxHeight] = useState(0) |
||||
const [lineChartList, setLineChartList] = useState(data) |
||||
|
||||
useEffect(() => { |
||||
setLineChartList(data) |
||||
setMaxHeight(data.reduce((pre, cur) => { |
||||
return Math.max(pre, cur.value) |
||||
}, 0)) |
||||
}, [data]) |
||||
|
||||
return ( |
||||
<ScrollView scrollX> |
||||
<View className={style.lineChart}> |
||||
{ |
||||
lineChartList.map(d => <View key={d.time}> |
||||
<View className={style.columnBox} style={{width: "100px"}}> |
||||
<View className={style.line} style={{height: height - 10 - (d.value / maxHeight * height) + "px"}}></View> |
||||
<View className={style.column} style={{height: d.value / maxHeight * height + "px"}}> </View> |
||||
<View>{d.time}</View> |
||||
</View> |
||||
</View>) |
||||
} |
||||
</View> |
||||
</ScrollView> |
||||
) |
||||
} |
||||
|
||||
export default LineChart |
@ -0,0 +1,42 @@ |
||||
import {FC} from "react"; |
||||
import {Image, Text, View} from "@tarojs/components"; |
||||
import styles from '../userInfo.module.scss' |
||||
|
||||
interface Props { |
||||
data: User | null |
||||
} |
||||
|
||||
const Info: FC<Props> = ({data}) => { |
||||
|
||||
|
||||
return ( |
||||
<> |
||||
<View className={styles.box}> |
||||
<Image src={data?.avatar || ''} className={styles.image}/> |
||||
<View className='ml-2'> |
||||
<View> |
||||
<Text className='font-weight'>{data?.name}</Text> |
||||
<Text |
||||
className={data?.is_lock ? styles.tag_muted : styles.tag}> |
||||
{data?.is_lock ? '禁用' : '正常'} |
||||
</Text> |
||||
</View> |
||||
<View className='text-muted font-24 mt-2'>{['学员', '管理员', '超级管理员'][data?.role_type || 0]}</View> |
||||
</View> |
||||
</View> |
||||
|
||||
<View className={`${styles.box} mt-3`} style={{display: 'block'}}> |
||||
<View className={styles.information} style={{borderBottom: "1px solid #F5F8F7"}}> |
||||
<Text style={{width: '100px', display: 'inline-block'}}>学员编号</Text> |
||||
<Text>{data?.id}号</Text> |
||||
</View> |
||||
<View className={styles.information}> |
||||
<Text style={{width: '100px', display: 'inline-block'}}>手机号</Text> |
||||
<Text>{data?.phone_number}</Text> |
||||
</View> |
||||
</View> |
||||
</> |
||||
) |
||||
} |
||||
|
||||
export default Info |
@ -0,0 +1,3 @@ |
||||
export default definePageConfig({ |
||||
navigationBarTitleText: '学员详情', |
||||
}) |
@ -0,0 +1,51 @@ |
||||
.page { |
||||
padding: 15rpx; |
||||
} |
||||
|
||||
.box { |
||||
background: #fff; |
||||
border-radius: 20rpx; |
||||
padding: 20rpx; |
||||
display: flex; |
||||
align-items: center; |
||||
box-sizing: border-box; |
||||
line-height: 1.75; |
||||
} |
||||
|
||||
.image { |
||||
width: 120rpx; |
||||
height: 120rpx; |
||||
background: #ddd; |
||||
border-radius: 10rpx; |
||||
overflow: hidden; |
||||
} |
||||
|
||||
.tag { |
||||
background: #00D6AC; |
||||
font-size: 24rpx; |
||||
color: #fff; |
||||
margin-left: 20rpx; |
||||
padding: 3rpx 10rpx; |
||||
border-radius: 8rpx; |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
.tag_muted { |
||||
background: #909795; |
||||
font-size: 24rpx; |
||||
color: #fff; |
||||
margin-left: 20rpx; |
||||
padding: 3rpx 10rpx; |
||||
border-radius: 8rpx; |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
.information { |
||||
width: 100%; |
||||
color: #606563; |
||||
padding: 20rpx 0; |
||||
} |
||||
|
||||
.total{ |
||||
text-align: center; |
||||
} |
@ -0,0 +1,140 @@ |
||||
import {Text, View} from "@tarojs/components"; |
||||
import {FC, useEffect, useState} from "react"; |
||||
import styles from './userInfo.module.scss' |
||||
import Taro from "@tarojs/taro"; |
||||
import Info from "@/pages/manage/userInfo/components/info"; |
||||
import Tabs, {OnChangOpt, TabList} from "@/components/tabs/tabs"; |
||||
import MyButton from "@/components/button/MyButton"; |
||||
import {ManageApi, StatisticsParam, userApi} from "@/api"; |
||||
import {Profile} from "@/store"; |
||||
import {everyDay, getMonday, getSunday, monthEnd, monthFirst} from "@/utils/time"; |
||||
import LineChart from "@/components/lineChart/lineChart"; |
||||
|
||||
|
||||
const tabList: TabList<any>[] = [ |
||||
{ |
||||
title: '日', |
||||
value: { |
||||
start_time: new Date().setHours(0, 0, 0, 0), |
||||
end_time: new Date().setHours(24, 0, 0, 0) |
||||
} |
||||
}, |
||||
{ |
||||
title: '周', value: { |
||||
start_time: getMonday(), |
||||
end_time: getSunday() |
||||
} |
||||
}, |
||||
{ |
||||
title: '月', value: { |
||||
start_time: monthFirst(), |
||||
end_time: monthEnd() |
||||
} |
||||
}, |
||||
] |
||||
|
||||
const UserInfo: FC = () => { |
||||
const {userId} = Taro.getCurrentInstance().router?.params as { userId: string } |
||||
const [data, setData] = useState<User | null>(null) |
||||
const [lineData, setLineData] = useState<any[]>([]) |
||||
const {user} = Profile.useContainer() |
||||
|
||||
function setRoleType() { |
||||
if (!data) return; |
||||
if (data.role_type === 2) { |
||||
Taro.showModal({title: "禁止修改超级管理员"}) |
||||
return |
||||
} |
||||
const type = data.role_type === 0 ? 1 : 0 |
||||
Taro.showModal({ |
||||
title: "设置为" + ['学员', '管理员'][type], |
||||
async success({confirm}) { |
||||
if (confirm) { |
||||
try { |
||||
await ManageApi.setRoleType(userId, {auth_id: user?.id!, role_type: type}) |
||||
Taro.showToast({title: "设置成功"}) |
||||
setData({ |
||||
...data, |
||||
role_type: type |
||||
}) |
||||
} catch (e) { |
||||
} |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
|
||||
function delUser() { |
||||
Taro.showModal({ |
||||
title: '是否确认删除', |
||||
async success({confirm}) { |
||||
if (confirm) { |
||||
await ManageApi.del(userId) |
||||
Taro.showToast({title: '删除成功'}) |
||||
Taro.navigateBack() |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
|
||||
async function getStatistics(data: StatisticsParam) { |
||||
try { |
||||
const res = await userApi.statistics(userId, data) |
||||
const everyDayValue = everyDay(data.start_time, Number(data.end_time), res.data) |
||||
setLineData(everyDayValue) |
||||
} catch (e) { |
||||
|
||||
} |
||||
} |
||||
|
||||
function tabChange({tab}: OnChangOpt<StatisticsParam>) { |
||||
getStatistics(tab?.value! as StatisticsParam) |
||||
} |
||||
|
||||
useEffect(() => { |
||||
getStatistics(tabList[0].value) |
||||
userApi.info(userId).then(res => { |
||||
setData(res) |
||||
}) |
||||
}, []) |
||||
|
||||
return ( |
||||
<View className={styles.page}> |
||||
<Info data={data}/> |
||||
|
||||
<View className={`${styles.box} mt-3`} style={{display: 'block'}}> |
||||
<Tabs tabList={tabList} onChange={tabChange}/> |
||||
<View className='font-weight font-36 mt-5 mb-3'> |
||||
总共学习 |
||||
<Text style={{margin: '0 10px', color: '#00D6AC'}}>121212</Text> |
||||
分钟 |
||||
</View> |
||||
<LineChart data={lineData}/> |
||||
</View> |
||||
|
||||
|
||||
<View className='mt-5'> |
||||
{ |
||||
data?.role_type !== 2 |
||||
&& <MyButton onClick={setRoleType}>{['设置为管理员', '设置为学员'][data?.role_type || 0]}</MyButton> |
||||
} |
||||
<MyButton |
||||
type='default' |
||||
style={{background: '#fff'}} |
||||
onClick={() => Taro.navigateTo({url: "/pages/manage/addStudent/addStudent?id=" + userId})} |
||||
className={'mt-3'}> |
||||
修改 |
||||
</MyButton> |
||||
<MyButton |
||||
type='default' |
||||
style={{background: '#fff', color: 'red'}} |
||||
className={'mt-3'} |
||||
onClick={delUser}> |
||||
删除 |
||||
</MyButton> |
||||
</View> |
||||
</View> |
||||
) |
||||
} |
||||
|
||||
export default UserInfo |
Loading…
Reference in new issue