修改我的页面布局样式

v2
king 1 year ago
parent 85da032f41
commit 389827ac79
  1. 17
      src/app.scss
  2. 8
      src/components/learningRecord/learningRecord.tsx
  3. 2
      src/components/lineChart/lineChart.module.scss
  4. 7
      src/components/lineChart/lineChart.tsx
  5. 6
      src/components/navigationBar/navigationBar.module.scss
  6. 20
      src/pages/home/components/feature.tsx
  7. 9
      src/pages/index/index.tsx
  8. 26
      src/pages/my/components/header/header.tsx
  9. 8
      src/pages/my/components/header/time.tsx
  10. 59
      src/pages/my/my.module.scss
  11. 175
      src/pages/my/my.tsx
  12. 3
      src/store/profile.ts

@ -60,7 +60,6 @@
.h-9 {height: 90vh} .h-9 {height: 90vh}
.h-10 {height: 100vh} .h-10 {height: 100vh}
.m-0 {margin: 0} .m-0 {margin: 0}
.m-auto{margin: auto} .m-auto{margin: auto}
.m-1 {margin: 10rpx} .m-1 {margin: 10rpx}
@ -353,4 +352,20 @@
-webkit-line-clamp:3; -webkit-line-clamp:3;
} }
.hr-solid,
.hr-dashed {
box-sizing: border-box;
height: 1px;
transform: scaleY(1);
border-bottom-color: #000;
border-bottom-width: 1px;
transform-origin: bottom center;
opacity: 0.05;
}
.hr-solid {
border-bottom-style: solid;
}
.hr-dashed {
border-bottom-style: dashed;
}

@ -2,7 +2,7 @@ import {Text, View} from "@tarojs/components";
import Tabs, {OnChangOpt, TabList} from "@/components/tabs/tabs"; import Tabs, {OnChangOpt, TabList} from "@/components/tabs/tabs";
import {everyDay, formatTime, getMonday, getSunday, monthEnd, monthFirst} from "@/utils/time"; import {everyDay, formatTime, getMonday, getSunday, monthEnd, monthFirst} from "@/utils/time";
import LineChart from "@/components/lineChart/lineChart"; import LineChart from "@/components/lineChart/lineChart";
import {FC, useEffect, useState} from "react"; import {CSSProperties, FC, useEffect, useState} from "react";
import {StatisticsParam, userApi} from "@/api"; import {StatisticsParam, userApi} from "@/api";
import styles from './learningRecord.module.scss' import styles from './learningRecord.module.scss'
import Spin from "@/components/spinner"; import Spin from "@/components/spinner";
@ -33,13 +33,15 @@ const tabList: TabList<any>[] = [
interface Props { interface Props {
userId?: string | number userId?: string | number
style?: CSSProperties
className?: string
} }
/** /**
* 线 * 线
*/ */
const LearningRecord: FC<Props> = ({userId}) => { const LearningRecord: FC<Props> = ({userId, style, className}) => {
const [lineData, setLineData] = useState<any[]>([]) const [lineData, setLineData] = useState<any[]>([])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const {token} = Profile.useContainer() const {token} = Profile.useContainer()
@ -69,7 +71,7 @@ const LearningRecord: FC<Props> = ({userId}) => {
userId && getStatistics(tabList[0].value) userId && getStatistics(tabList[0].value)
}, [userId]) }, [userId])
return (<View className={styles.box} style={{display: 'block'}}> return (<View className={[styles.box, className].filter(Boolean).join(' ')} style={{display: 'block', ...style}}>
<Tabs tabList={tabList} onChange={tabChange} backMode/> <Tabs tabList={tabList} onChange={tabChange} backMode/>
<View style={{position: "relative"}}> <View style={{position: "relative"}}>
<Spin enable={loading} block/> <Spin enable={loading} block/>

@ -26,7 +26,7 @@
font-family: PingFang SC-Medium, PingFang SC; font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500; font-weight: 500;
color: #323635; color: #323635;
margin-top: 18rpx; margin-top: 10rpx;
margin-bottom: 42rpx; margin-bottom: 42rpx;
} }

@ -37,11 +37,14 @@ const LineChart: FC<Props> = ({data}) => {
<View className={style.lineChart}> <View className={style.lineChart}>
{!maxHeight.value && <View className={style.empty}></View>} {!maxHeight.value && <View className={style.empty}></View>}
{ {
!!maxHeight.value && lineChartList.map(d => <View key={d.time}> !!maxHeight.value
&& lineChartList.map(d => <View key={d.time}>
<View className={style.columnBox} style={{width: "100px"}}> <View className={style.columnBox} style={{width: "100px"}}>
<View className={style.line} <View className={style.line}
style={{height: height - 10 - (d.value / maxHeight.value * height) + "px"}}></View> style={{height: height - 10 - (d.value / maxHeight.value * height) + "px"}}></View>
{d.value > 0 && <View style={{whiteSpace: "nowrap"}}>{formatTime(d.value, 0)}</View>} {
d.value > 0 && <View style={{whiteSpace: "nowrap"}}>{formatTime(d.value, 0)}</View>
}
<View className={style.column} style={{height: d.value / maxHeight.value * height + "px"}}/> <View className={style.column} style={{height: d.value / maxHeight.value * height + "px"}}/>
<View>{d.time}</View> <View>{d.time}</View>
</View> </View>

@ -4,7 +4,7 @@
left: 0; left: 0;
width: 100%; width: 100%;
padding-left: 20rpx; padding-left: 20rpx;
z-index: 10; z-index: 100;
overflow: hidden; overflow: hidden;
background: #fff; background: #fff;
} }
@ -12,7 +12,7 @@
.leftNode { .leftNode {
position: absolute; position: absolute;
display: flex; display: flex;
left: 0; left: 20rpx;
bottom: 0; bottom: 0;
align-items: center; align-items: center;
z-index: 1; z-index: 1;
@ -20,7 +20,7 @@
.text { .text {
position: absolute; position: absolute;
left: 0; left: 20rpx;
right: 0; right: 0;
margin: auto; margin: auto;
display: flex; display: flex;

@ -7,18 +7,18 @@ import article from '@/static/img/article.png'
import styles from '../home.module.scss' import styles from '../home.module.scss'
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
const Feature: FC = () => { const list = [
const list = [ {url: '/pages/preview/brand/list/list', image: article, text: '企业品牌'},
{url: '/pages/preview/brand/list/list', image: article, text: '品牌'}, {url: '/pages/preview/health/health', image: health, text: '健康常识'},
{url: '/pages/preview/health/health', image: health, text: '健康管理'}, {url: '/pages/preview/profession/profession', image: profession, text: '专业技能'},
{url: '/pages/preview/profession/profession', image: profession, text: '专业技能'}, {url: '/pages/preview/illness/sort/sort', image: illness, text: '病症百科'},
{url: '/pages/preview/illness/sort/sort', image: illness, text: '病症百科'}, ]
]
function jump(url) { function jump(url) {
Taro.navigateTo({url}) Taro.navigateTo({url})
} }
const Feature: FC = () => {
return ( return (
<View className='flex justify-around' style={{marginBottom: '20px'}}> <View className='flex justify-around' style={{marginBottom: '20px'}}>
{ {

@ -6,11 +6,12 @@ import Tabs, {OnChangOpt, TabList} from "@/components/tabs/tabs";
import {CoursesKey} from "@/api/public"; import {CoursesKey} from "@/api/public";
import NavigationBar from "@/components/navigationBar/navigationBar"; import NavigationBar from "@/components/navigationBar/navigationBar";
const category: TabList[] = [
{title: "企选课程", value: 'is_required'},
{title: "平台课程", value: 'is_not_required'},
]
const Index: FC = () => { const Index: FC = () => {
const category: TabList[] = [
{title: "必修", value: 'is_required'},
{title: "选修", value: 'is_not_required'},
]
const [categoryKey, setCategoryKey] = useState<CoursesKey>('is_required') const [categoryKey, setCategoryKey] = useState<CoursesKey>('is_required')
function tabChange(data: OnChangOpt) { function tabChange(data: OnChangOpt) {

@ -3,7 +3,7 @@ import {Image, Text, View} from "@tarojs/components";
import styles from "@/pages/my/my.module.scss"; import styles from "@/pages/my/my.module.scss";
import avatar from "@/static/img/avatar.png" import avatar from "@/static/img/avatar.png"
import blacktriang from "@/static/img/blacktriangle.png" import blacktriang from "@/static/img/blacktriangle.png"
import {FC} from "react"; import {FC, useMemo} from "react";
import Img from "@/components/image/image"; import Img from "@/components/image/image";
interface Props { interface Props {
@ -13,23 +13,21 @@ interface Props {
const Header: FC<Props> = ({companyList, showCompany}) => { const Header: FC<Props> = ({companyList, showCompany}) => {
const {token, user, company, empty} = Profile.useContainer() const {token, user, company, empty} = Profile.useContainer()
const login = () => empty()
const showChoose = useMemo(() => (token?.length ?? 0) > 0 && companyList.length >2, [token, companyList])
return ( return (
<View className={styles.header}> <View className={styles.header}>
<View className='flex'> <View className='flex'>
<Img width={100} height={100} src={user?.avatar || avatar} className={styles.avatar} errorType='avatar'/> <Img width={100} height={100} src={user?.avatar || avatar} className={`${styles.avatar} rounded-50`} errorType='avatar' onClick={token ? undefined : login} />
{ <View className='flex-1 flex flex-column justify-start align-start mt-1'>
token ? <View className='flex-1 mt-1'> <View className='font-32' onClick={token ? undefined : login}>{token ? user?.name ?? '匿名' : '请登录'}</View>
<View className='font-32'>{user?.name}</View> <View className='flex align-center mt-1' onClick={token ? showCompany : login}>
<View className='flex align-center mt-2' onClick={showCompany}> <Text style={{fontSize: '24rpx', fontWeight: '500', color: '#323635'}}>{token ? company?.name : '登录解锁更多功能哦'}</Text>
<Text style={{fontSize: '24rpx', fontWeight: '500', color: '#323635'}}>{company?.name}</Text> {showChoose && <Image src={blacktriang} style={{width: '20rpx', height: '20rpx'}}/>}
{companyList.length > 2 && <Image src={blacktriang} style={{width: '20rpx', height: '20rpx'}}/>} </View>
</View> </View>
</View>
: <View className='flex-1'>
<View className='font-32 mt-2' onClick={() => empty()}></View>
</View>
}
</View> </View>
</View> </View>
) )

@ -6,8 +6,8 @@ import {FC, useState} from "react";
import {formatMinute} from "@/utils/time"; import {formatMinute} from "@/utils/time";
import time1 from "@/static/img/time1.png"; import time1 from "@/static/img/time1.png";
import time2 from "@/static/img/time2.png"; import time2 from "@/static/img/time2.png";
import over from '@/static/img/over.png' // import over from '@/static/img/over.png'
import incomplete from '@/static/img/incomplete.png' // import incomplete from '@/static/img/incomplete.png'
import {Profile} from "@/store"; import {Profile} from "@/store";
interface List { interface List {
@ -24,8 +24,8 @@ const Time: FC = () => {
{title: '累计时长', time: '00:00', src: time2}, {title: '累计时长', time: '00:00', src: time2},
// {title: '必修课', time: '0', src: curriculum1, type: 1}, // {title: '必修课', time: '0', src: curriculum1, type: 1},
// {title: '选修课', time: '0', src: curriculum2, type: 2}, // {title: '选修课', time: '0', src: curriculum2, type: 2},
{title: '已完成', time: '0', src: over, type: 3}, // {title: '已完成', time: '0', src: over, type: 3},
{title: '未完成(必修)', time: '0', src: incomplete, type: 4}, // {title: '未完成(必修)', time: '0', src: incomplete, type: 4},
]) ])

@ -10,10 +10,21 @@ page {
align-items: center; align-items: center;
} }
.page { .navbar {
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.bg {
z-index: 1;
position: absolute;
overflow: hidden;
top: 0;
left: 0;
right: 0;
height: 460rpx;
background: linear-gradient(180deg, #45D4A8 0%, rgba(69, 212, 168, 0) 100%) no-repeat; background: linear-gradient(180deg, #45D4A8 0%, rgba(69, 212, 168, 0) 100%) no-repeat;
background-size: 100% 458rpx; background-size: 100% 458rpx;
width: 100%;
&:before { &:before {
content: ''; content: '';
@ -27,14 +38,50 @@ page {
opacity: 0.2; opacity: 0.2;
border-radius: 230rpx; border-radius: 230rpx;
} }
&:after {
content: '';
display: block;
position: absolute;
top: 0rpx;
right: -100rpx;
width: 290rpx;
height: 290rpx;
background: #FFFF;
opacity: 0.2;
border-radius: 290rpx;
}
} }
/*.page {
background: linear-gradient(180deg, #45D4A8 0%, rgba(69, 212, 168, 0) 100%) no-repeat;
background-size: 100% 458rpx;
width: 100%;
overflow: hidden;
&:before {
content: '';
display: block;
position: absolute;
top: -80rpx;
left: -80rpx;
width: 230rpx;
height: 230rpx;
background: #FFFF;
opacity: 0.2;
border-radius: 230rpx;
}
}*/
.content { .content {
z-index: 8;
position: relative;
box-sizing: border-box; box-sizing: border-box;
padding: 0 30rpx; padding: 0 30rpx 24rpx;
width: 100%; width: 100%;
//overflow: hidden;
&:after { /* &:after {
content: ''; content: '';
display: block; display: block;
position: absolute; position: absolute;
@ -45,7 +92,7 @@ page {
background: #FFFF; background: #FFFF;
opacity: 0.2; opacity: 0.2;
border-radius: 290rpx; border-radius: 290rpx;
} }*/
} }
@ -109,7 +156,7 @@ page {
background: #fff; background: #fff;
border-radius: 20rpx; border-radius: 20rpx;
padding: 30rpx; padding: 30rpx;
margin-top: 30rpx; //margin-top: 30rpx;
} }
.box { .box {

@ -1,4 +1,4 @@
import {PageContainer, View, Image, ScrollView, Text} from "@tarojs/components"; import {PageContainer, View, Image, Text} from "@tarojs/components";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import styles from './my.module.scss' import styles from './my.module.scss'
import Header from "./components/header/header"; import Header from "./components/header/header";
@ -22,6 +22,15 @@ interface List {
type?: number type?: number
} }
function jump(token: string | null, type?: number) {
if (!token) {
Taro.navigateTo({url: '/pages/login/login'})
return;
}
if (!type) return;
Taro.navigateTo({url: "/pages/business/courType/courType?type=" + type})
}
const My: FC = () => { const My: FC = () => {
const globalData = Taro.getApp().globalData const globalData = Taro.getApp().globalData
const {token, company, setCompany, user} = Profile.useContainer() const {token, company, setCompany, user} = Profile.useContainer()
@ -29,8 +38,6 @@ const My: FC = () => {
const [companyList, setCompanyList] = useState<Company[]>([]) const [companyList, setCompanyList] = useState<Company[]>([])
const [navbarOpacity, setNavbarOpacity] = useState('0') const [navbarOpacity, setNavbarOpacity] = useState('0')
const navbarHeight = globalData.statusBarHeight + globalData.textBarHeight; const navbarHeight = globalData.statusBarHeight + globalData.textBarHeight;
const pageHeight = globalData.windowHeight - globalData.textBarHeight - globalData.statusBarHeight
Taro.useDidShow(() => { Taro.useDidShow(() => {
token && userApi.companyList().then(res => { token && userApi.companyList().then(res => {
@ -38,19 +45,18 @@ const My: FC = () => {
}) })
}) })
function onScroll(e) { Taro.usePageScroll((e) => {
const v = (Math.min(e.detail.scrollTop / navbarHeight, 1) * 0.9).toFixed(6) const v = (Math.min(e.scrollTop / navbarHeight, 1) * 0.9).toFixed(6)
if (v != navbarOpacity) { if (v != navbarOpacity) {
setNavbarOpacity(v) setNavbarOpacity(v)
} }
} })
const [list, setList] = useState<List[]>([ const [list, setList] = useState<List[]>([
{title: '已完成', time: '0', src: over, type: 3}, {title: '已完成', time: '0', src: over, type: 3},
{title: '未完成', time: '0', src: incomplete, type: 4}, {title: '未完成', time: '0', src: incomplete, type: 4},
]) ])
Taro.useDidShow(async () => { Taro.useDidShow(async () => {
try { try {
const res = await curriculum.course() const res = await curriculum.course()
@ -62,83 +68,106 @@ const My: FC = () => {
} }
}) })
return ( return (
<View className={styles.page}> <View>
<NavigationBar <NavigationBar
className={styles.navbar}
backgroundColor={`rgba(255,255,255,${navbarOpacity})`} backgroundColor={`rgba(255,255,255,${navbarOpacity})`}
cancelBack> cancelBack
{ leftNode={
<View className={styles.navigation} <View className={styles.navigation}
style={{transform: `translate(0,${Number(navbarOpacity) > .5 ? "0%" : '-300%'})`}}> style={{transform: `translate(0,${Number(navbarOpacity) > .5 ? "0%" : '-350%'})`}}>
<Img src={user?.avatar || avatar} mode='heightFix' width={50} height={50} errorType='avatar'/> <Img className="rounded-50" src={user?.avatar || avatar} mode='heightFix' width={50} height={50}
<Text className='pl-2'>{user?.name}</Text> errorType='avatar'/>
<Text className='pl-2'>{token ? user?.name : '请登录'}</Text>
</View> </View>
} }
</NavigationBar> />
<ScrollView scrollY enhanced showScrollbar={false} style={{height: pageHeight}} onScroll={onScroll}> <View className={styles.bg}/>
<View className={styles.content}>
<View style={{opacity: 1 - Number(navbarOpacity)}}>
<Header companyList={companyList} showCompany={() => companyList.length >= 2 && setCompanyShow(true)}/>
</View>
<Time/>
<View> <View className={styles.content}>
<LearningRecord userId={user?.id}/> <View className='mb-4' style={{opacity: 1 - Number(navbarOpacity)}}>
<Service/> <Header companyList={companyList} showCompany={() => companyList.length >= 2 && setCompanyShow(true)}/>
</View> </View>
<Time/>
<PageContainer <View className="bg-white rounded-20 mb-2 clip">
overlayStyle={'background:rgba(0,0,0,0.3)'} <View className="flex p-2">
position='bottom' {list.map((d) => (
round <View className={styles.timeBox} style={{marginBottom: '0 !important'}} key={d.title}
show={companyShow} onClick={() => jump(token, d.type)}>
onClickOverlay={() => setCompanyShow(false)}> <View className={styles.timeBoxFlex}
<View className="px-3 py-5"> style={{backgroundColor: 'rgba(0,0,0,0.02)', borderRadius: '16rpx'}}>
<View className="font-32 pb-3" <View>
style={{ <View className='mb-2 font-28 font-weight'>{d.title}</View>
display: 'flex', <View className='text-muted font-26 mt-1'>{d.time}</View>
justifyContent: 'center',
borderBottom: '2rpx solid #f5f8f7'
}}></View>
{
companyList.length >= 1 &&
companyList.map((d, idx) =>
<View className={`${styles.box} ${companyList.length - 1 === idx && styles.noBorder} `}
onClick={async () => {
if (company?.id === d.id) return;
Taro.showLoading({
title: '切换公司中',
mask: true,
})
const data = await userApi.companyReplace(d.id)
Taro.hideLoading()
!data && setCompany(d)
!data && Taro.showModal({
title: '友情提示',
content: '切换公司成功,需要重新进入',
showCancel: false,
success: function (res) {
res.confirm && Taro.reLaunch({url: '/pages/my/my'})
}
})
setCompanyShow(false)
}}>
<View className={styles.image}>
<Img width={68} height={68} src={d.logo}/>
</View>
<View className={styles.innerBox}>
<View className={styles.title}>{d.name}</View>
<Image src={company?.id === d.id ? GreenNike : ''} className={styles.icon}></Image>
</View>
</View> </View>
) <Image src={d.src} mode='aspectFit' className={styles.timeImag}/>
} </View>
</View> </View>
</PageContainer> ))}
</View>
{
token && (<View className="p-2">
<LearningRecord style={{paddingTop: '0 !important'}} userId={user?.id}/>
</View>)
}
</View> </View>
</ScrollView>
<Service/>
<PageContainer
overlayStyle={'background:rgba(0,0,0,0.3)'}
position='bottom'
round
show={companyShow}
onClickOverlay={() => setCompanyShow(false)}>
<View className="px-3 py-5">
<View className="font-32 pb-3" style={{
display: 'flex',
justifyContent: 'center',
borderBottom: '2rpx solid #f5f8f7'
}}>
</View>
{
companyList.length >= 1 &&
companyList.map((d, idx) =>
<View className={`${styles.box} ${companyList.length - 1 === idx && styles.noBorder} `}
onClick={async () => {
if (company?.id === d.id) return;
Taro.showLoading({
title: '切换公司中',
mask: true,
})
const data = await userApi.companyReplace(d.id)
Taro.hideLoading()
!data && setCompany(d)
!data && Taro.showModal({
title: '友情提示',
content: '切换公司成功,需要重新进入',
showCancel: false,
success: function (res) {
res.confirm && Taro.reLaunch({url: '/pages/my/my'})
}
})
setCompanyShow(false)
}}>
<View className={styles.image}>
<Img width={68} height={68} src={d.logo}/>
</View>
<View className={styles.innerBox}>
<View className={styles.title}>{d.name}</View>
<Image src={company?.id === d.id ? GreenNike : ''} className={styles.icon}></Image>
</View>
</View>
)
}
</View>
</PageContainer>
</View>
</View> </View>
) )
} }

@ -53,7 +53,7 @@ function useProfile() {
const [company, setCompany] = useState<Company | null>(data?.company || null) const [company, setCompany] = useState<Company | null>(data?.company || null)
function empty(jump = true,relaunch=false) { function empty(jump = true, relaunch=false) {
setUser(null) setUser(null)
setUser(null) setUser(null)
setToken(null) setToken(null)
@ -63,7 +63,6 @@ function useProfile() {
jump && Taro.reLaunch({url: '/pages/my/my'}) jump && Taro.reLaunch({url: '/pages/my/my'})
}else{ }else{
jump && Taro.navigateTo({url: '/pages/login/login'}) jump && Taro.navigateTo({url: '/pages/login/login'})
} }
} }

Loading…
Cancel
Save