1.修改个人中心手机号和新增上传头像

2.工具服务登录后权限渲染
3.切换公司仅只有一个公司时不进行操作
4.修改首页切换和加载更多样式
v2
king 1 year ago
parent 19e01cf623
commit 54e581f2ae
  1. 4
      .env
  2. 4
      src/api/user.ts
  3. 1
      src/components/navigationBar/navigationBar.module.scss
  4. 2
      src/components/popPut/popPut.tsx
  5. 25
      src/hooks/eventsIndex.ts
  6. 11
      src/pages/business/courType/courType.tsx
  7. 59
      src/pages/business/userInfo/userInfo.tsx
  8. 2
      src/pages/business/videoInfo/videoInfo.tsx
  9. 35
      src/pages/index/components/videoList.tsx
  10. 2
      src/pages/index/index.tsx
  11. 43
      src/pages/my/components/header/header.tsx
  12. 36
      src/pages/my/components/header/service.tsx
  13. 81
      src/pages/my/my.tsx

@ -1,5 +1,5 @@
#TARO_APP_API=https://yjx.dev.yaojiankang.top TARO_APP_API=https://yjx.dev.yaojiankang.top
TARO_APP_API=https://mooc.yaojiankang.top #TARO_APP_API=https://mooc.yaojiankang.top
#TARO_APP_API=https://shopfix.yaojiankang.top #TARO_APP_API=https://shopfix.yaojiankang.top
#TARO_APP_API=https://playedu.yaojiankang.top #TARO_APP_API=https://playedu.yaojiankang.top
TARO_APP_LGOIN=true TARO_APP_LGOIN=true

@ -94,4 +94,8 @@ export const userApi = {
companyReplace(id: number) { companyReplace(id: number) {
return request(`/api/v1/company/replace/${id}`, "PATCH") return request(`/api/v1/company/replace/${id}`, "PATCH")
}, },
// /** 上传头像 */
// putAvatar(file: string) {
// return request('/api/v1/user/avatar', "PUT", {file})
// }
} }

@ -15,6 +15,7 @@
left: 0; left: 0;
bottom: 0; bottom: 0;
align-items: center; align-items: center;
z-index: 1;
} }
.text { .text {

@ -52,8 +52,8 @@ const PopPut: FC<Props> = ({title, chevron, content, image, isProp, children, sh
</View> </View>
<View className='card-content'> <View className='card-content'>
<View>{content}</View> <View>{content}</View>
{!chevron && <Icon name='chevron-right'/>}
{image && <Img src={image} mode='scaleToFill' className='image' width={68} height={68}/>} {image && <Img src={image} mode='scaleToFill' className='image' width={68} height={68}/>}
{!chevron && <Icon name='chevron-right'/>}
</View> </View>
</View> </View>
{ {

@ -1,25 +0,0 @@
import Taro from "@tarojs/taro";
/**
*
* -
*/
const KEY = 'REFRESH_INDEX'
interface RefreshIndex {
id: number
}
function on(fn: (arg: RefreshIndex) => void) {
Taro.eventCenter.on(KEY, fn)
}
function trigger(data: RefreshIndex) {
Taro.eventCenter.trigger(KEY, data)
}
export default {
on,
trigger
}

@ -5,7 +5,6 @@ import {courseApi} from "@/api";
import VideoCover from "@/components/videoCover/videoCover"; import VideoCover from "@/components/videoCover/videoCover";
import {formatMinute} from "@/utils/time"; import {formatMinute} from "@/utils/time";
import Empty from "@/components/empty/empty"; import Empty from "@/components/empty/empty";
import eventsIndex from "@/hooks/eventsIndex";
const CourType: FC = () => { const CourType: FC = () => {
const params = useRouter().params const params = useRouter().params
@ -46,16 +45,6 @@ const CourType: FC = () => {
} }
} }
eventsIndex.on(({id}) => {
if (id == null && params.type === "4") return;
for (const [index, notFinished] of data.entries()) {
if (notFinished.id === id) {
data.splice(index, 1)
return
}
}
})
useEffect(() => { useEffect(() => {
getData() getData()

@ -1,6 +1,5 @@
import {useState} from "react"; import {useState} from "react";
import {Profile} from '@/store' import {Profile} from '@/store'
import avatar from "@/static/img/avatar.png"
import PopPut from "@/components/popPut/popPut"; import PopPut from "@/components/popPut/popPut";
import {Input, View} from "@tarojs/components"; import {Input, View} from "@tarojs/components";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
@ -10,7 +9,7 @@ import MyButton from "@/components/button/MyButton";
const List = () => { const List = () => {
const {empty, user, setUser} = Profile.useContainer() const {empty, user, setUser, token} = Profile.useContainer()
const [show, setShow] = useState(false) const [show, setShow] = useState(false)
const [name, setName] = useState<string>(user?.name || '') const [name, setName] = useState<string>(user?.name || '')
@ -45,17 +44,67 @@ const List = () => {
Taro.showModal({ Taro.showModal({
title: '是否确定退出登录', title: '是否确定退出登录',
success({confirm}) { success({confirm}) {
confirm && empty(true,true) confirm && empty(true, true)
} }
}) })
} }
function putAvatar(filePath: string) {
Taro.showLoading({title: "正在上传图片"})
Taro.uploadFile({
url: process.env.TARO_APP_API + '/api/v1/user/avatar',
filePath,
name: 'file',
header: {
'Authorization': `Bearer ${token}`
},
success(res) {
Taro.hideLoading()
if (res.statusCode === 200) {
const data: User = JSON.parse(res.data).data
setUser(data)
Taro.showToast({title: "图片上传成功"})
} else {
Taro.showToast({title: "图片上传失败", icon: 'error'})
}
},
fail() {
Taro.showToast({title: "图片上传失败", icon: 'error'})
}
})
}
function selectAvatar() {
Taro.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: async (res) => {
if (!res.tempFiles.length) return;
const file = res.tempFiles[0]
if (file.size > 40960000) {
Taro.compressImage({
src: file.path,
quality: 50,
compressedWidth: 50,
compressHeight: 50,
success(res) {
putAvatar(res.tempFilePath)
}
})
} else {
putAvatar(file.path)
}
}
})
}
return ( return (
<> <>
<View className={styles.box}> <View className={styles.box}>
<PopPut title='头像' image={avatar} chevron no_border/> <PopPut title='头像' image={user?.avatar} no_border onClick={selectAvatar}/>
<PopPut title='手机号' content={user?.phone_number} chevron no_border/> <PopPut title='手机号' content={user?.phone_number?.replace(user?.phone_number.slice(3, 7), "****")} chevron
no_border/>
<PopPut title='昵称' content={user?.name} isProp show={show} no_border> <PopPut title='昵称' content={user?.name} isProp show={show} no_border>
<View className='p-2'> <View className='p-2'>
<View className='text-center font-weigh mb-3'></View> <View className='text-center font-weigh mb-3'></View>

@ -5,7 +5,6 @@ import './videoInfo.scss'
import Catalogue from "./components/catalogue"; import Catalogue from "./components/catalogue";
import Course from "./components/course"; import Course from "./components/course";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import eventsIndex from "@/hooks/eventsIndex";
import {formatMinute} from "@/utils/time"; import {formatMinute} from "@/utils/time";
import videoEvents from "@/hooks/videoEvents"; import videoEvents from "@/hooks/videoEvents";
import unique_ident from "@/hooks/unique_ident"; import unique_ident from "@/hooks/unique_ident";
@ -52,7 +51,6 @@ const VideoInfo: FC = () => {
const flats: Hour[] = Object.values(data?.hours || {}).flat(Infinity) as Hour[] const flats: Hour[] = Object.values(data?.hours || {}).flat(Infinity) as Hour[]
if (playId === flats?.[flats.length - 1]?.id && !preview) { if (playId === flats?.[flats.length - 1]?.id && !preview) {
Taro.showModal({title: '当前课程结束'}) Taro.showModal({title: '当前课程结束'})
eventsIndex.trigger({id: Number(id)})
return; return;
} }
for (const [index, flat] of flats.entries()) { for (const [index, flat] of flats.entries()) {

@ -19,8 +19,6 @@ export const VideoList: FC<Props> = ({categoryKey, setCategoryKey}) => {
const [data, setData] = useState<Courses>({ const [data, setData] = useState<Courses>({
is_required: [], is_required: [],
is_not_required: [], is_not_required: [],
// is_finished: [],
// is_not_finished: [],
}) })
const [page, setPage] = useState(1) const [page, setPage] = useState(1)
const [records, setRecords] = useState<LearnRecord[]>([]) const [records, setRecords] = useState<LearnRecord[]>([])
@ -45,8 +43,6 @@ export const VideoList: FC<Props> = ({categoryKey, setCategoryKey}) => {
setData({ setData({
is_required: screen(old.is_required, res.is_required || []), is_required: screen(old.is_required, res.is_required || []),
is_not_required: screen(old.is_not_required, res.is_not_required || []), is_not_required: screen(old.is_not_required, res.is_not_required || []),
// is_finished: screen(old.is_finished, res.is_finished || []),
// is_not_finished: screen(old.is_not_finished, res.is_not_finished || []),
}) })
} catch (e) { } catch (e) {
} }
@ -76,16 +72,6 @@ export const VideoList: FC<Props> = ({categoryKey, setCategoryKey}) => {
} }
} }
// eventsIndex.on(({id}) => {
// if (id == null) return;
// for (const [index, notFinished] of data.is_not_finished.entries()) {
// if (notFinished.id === id) {
// data.is_finished.push(notFinished)
// data.is_not_finished.splice(index, 1)
// return
// }
// }
// })
const fetchData = () => { const fetchData = () => {
getData().then() getData().then()
@ -114,12 +100,11 @@ export const VideoList: FC<Props> = ({categoryKey, setCategoryKey}) => {
Object.entries(data).map(([key, value]) => <SwiperItem> Object.entries(data).map(([key, value]) => <SwiperItem>
<ScrollView scrollY className={styles.swiper} onScrollToLower={() => setPage(page + 1)} enhanced <ScrollView scrollY className={styles.swiper} onScrollToLower={() => setPage(page + 1)} enhanced
showScrollbar={false}> showScrollbar={false}>
<View className='py-2 flex justify-between flex-wrap'> {
{ !token && key === 'is_required'
!token ? <LoginView onSuccess={fetchData}/> : value?.length ?
&& key === 'is_required' <>
? <LoginView onSuccess={fetchData}/> : value?.length ? <View className='py-2 flex justify-between flex-wrap'>
<>
{ {
value?.map(c => value?.map(c =>
<VideoCover <VideoCover
@ -132,11 +117,11 @@ export const VideoList: FC<Props> = ({categoryKey, setCategoryKey}) => {
content={rateOfLearning(c.id, c.class_hour)} content={rateOfLearning(c.id, c.class_hour)}
/>) />)
} }
<View className='text-center text-muted flex-1'></View> </View>
</> <View className='text-center text-muted'></View>
: <Empty name='暂无课程'/> </>
} : <Empty name='暂无课程'/>
</View> }
</ScrollView> </ScrollView>
</SwiperItem>) </SwiperItem>)
} }

@ -10,8 +10,6 @@ const Index: FC = () => {
const category: TabList[] = [ const category: TabList[] = [
{title: "必修", value: 'is_required'}, {title: "必修", value: 'is_required'},
{title: "选修", value: 'is_not_required'}, {title: "选修", value: 'is_not_required'},
// {title: "已完成", value: 'is_finished'},
// {title: "未完成", value: 'is_not_finished'},
] ]
const [categoryKey, setCategoryKey] = useState<CoursesKey>('is_required') const [categoryKey, setCategoryKey] = useState<CoursesKey>('is_required')

@ -3,39 +3,32 @@ 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";
const Header = ({showCompany}:{showCompany:()=> void}) => { interface Props {
const {token,user,company,empty} = Profile.useContainer() companyList: Company[]
showCompany: () => void
}
const Header: FC<Props> = ({companyList, showCompany}) => {
const {token, user, company, empty} = Profile.useContainer()
return ( return (
<View className={styles.header}> <View className={styles.header}>
<View className='flex'> <View className='flex'>
<Image src={user?.avatar || avatar} className={styles.avatar}/>
{ {
token ? token ? <View className='flex-1'>
<Image src={user?.avatar || avatar} className={styles.avatar}/>: <View className='font-32'>{user?.name}</View>
<Image src={avatar} className={styles.avatar}/> <View className='flex align-center mt-2' onClick={showCompany}>
} <Text style={{fontSize: '24rpx', fontWeight: '500', color: '#323635'}}>{company?.name}</Text>
{ token ? {companyList.length > 2 && <Image src={blacktriang} style={{width: '20rpx', height: '20rpx'}}></Image>}
<View className='flex-1'> </View>
<View className='font-32'>{user?.name}</View> </View>
: <View className='flex-1'>
<View className='flex align-center mt-2' onClick={()=>{ <View className='font-32 mt-2' onClick={() => empty()}></View>
showCompany()
}}>
<Text style={{fontSize:'24rpx',fontWeight:'500',color:'#323635'}}>{company?.name}</Text>
<Image src={blacktriang} style={{width:'20rpx',height:'20rpx'}}></Image>
</View> </View>
</View>:
<View className='flex-1'>
<View className='font-32 mt-2' onClick={()=>{
empty()
}}></View>
</View>
} }
{/*<View className='login font-24 mt-2 text-secondary flex justify-between content-start'>*/}
{/* <Text>手机号:{user?.phone_number}</Text>*/}
{/*</View>*/}
</View> </View>
</View> </View>
) )

@ -1,4 +1,4 @@
import {useEffect, useState} from "react"; import {useState} from "react";
import {Image, View} from "@tarojs/components"; import {Image, View} from "@tarojs/components";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import {Profile} from '@/store/profile' import {Profile} from '@/store/profile'
@ -22,7 +22,7 @@ const Service = () => {
{title: '个人中心', src: userInfo, router: '/pages/business/userInfo/userInfo'}, {title: '个人中心', src: userInfo, router: '/pages/business/userInfo/userInfo'},
]) ])
const {token,user, setUser} = Profile.useContainer() const {token, user, setUser} = Profile.useContainer()
Taro.useDidShow(async () => { Taro.useDidShow(async () => {
if (user?.id) { if (user?.id) {
@ -31,24 +31,26 @@ const Service = () => {
} }
}) })
useEffect(() => { Taro.useDidShow(() => {
const oldList: List[] = JSON.parse(JSON.stringify(list)) if ([1, 2].includes(user?.role_type || 0)) {
if(token){ setList([
if ([1, 2].includes(user?.role_type || 0)) { {title: '部门管理', src: dep, router: '/pages/manage/depAdmin/depAdmin'},
oldList.unshift(...[ {title: '现场会', src: spotMeeting, router: '/pages/manage/spotMeeting/spotMeeting'},
{title: '部门管理', src: dep, router: '/pages/manage/depAdmin/depAdmin'}, {title: '课程管理', src: course, router: '/pages/manage/courseAdmin/courseAdmin'},
// {title: '课程市场', src: buy, router: '/pages/manage/curriculum/curriculum'}, {title: '个人中心', src: userInfo, router: '/pages/business/userInfo/userInfo'},
{title: '现场会', src: spotMeeting, router: '/pages/manage/spotMeeting/spotMeeting'}, {title: '历史记录', src: cur, router: '/pages/business/history/history'},
{title: '课程管理', src: course, router: '/pages/manage/courseAdmin/courseAdmin'}, ])
]) } else {
setList(oldList) setList([
} {title: '历史记录', src: cur, router: '/pages/business/history/history'},
{title: '个人中心', src: userInfo, router: '/pages/business/userInfo/userInfo'},
])
} }
}, []) })
function jump(url: string) { function jump(url: string) {
if(!token){ if (!token) {
Taro.navigateTo({url:'/pages/login/login'}) Taro.navigateTo({url: '/pages/login/login'})
return return
} }
Taro.navigateTo({url}) Taro.navigateTo({url})

@ -16,58 +16,57 @@ const My: FC = () => {
const [companyShow, setCompanyShow] = useState(false) const [companyShow, setCompanyShow] = useState(false)
const [companyList, setCompanyList] = useState<Company[]>([]) const [companyList, setCompanyList] = useState<Company[]>([])
Taro.useDidShow(() => { Taro.useDidShow(() => {
if(token){ token && userApi.companyList().then(res => {
try { setCompanyList(res as Company[])
userApi.companyList().then(res => { })
setCompanyList(res as Company[])
})
} catch (e) {
}
}
}) })
return ( return (
<View className={styles.content} style={`paddingTop:${globalData.statusBarHeight}px`}> <View className={styles.content} style={`paddingTop:${globalData.statusBarHeight}px`}>
<Header showCompany={()=>{ <Header companyList={companyList} showCompany={() => companyList.length >= 2 && setCompanyShow(true)}/>
companyList.length >= 2 && setCompanyShow(true) <Time/>
}}/> {token && <Service/>}
<Time/>
<Service/>
<PageContainer overlayStyle={'background:rgba(0,0,0,0.3)'} position={'bottom'} round={true} show={companyShow} <PageContainer
onClickOverlay={() => setCompanyShow(false)}> overlayStyle={'background:rgba(0,0,0,0.3)'}
position='bottom'
round
show={companyShow}
onClickOverlay={() => setCompanyShow(false)}>
<View className="px-3 py-5"> <View className="px-3 py-5">
<View className="font-32 pb-3" <View className="font-32 pb-3"
style={{display: 'flex', justifyContent: 'center', borderBottom: '2rpx solid #f5f8f7'}}></View> style={{
display: 'flex',
justifyContent: 'center',
borderBottom: '2rpx solid #f5f8f7'
}}></View>
{ {
companyList.length >= 1 && companyList.length >= 1 &&
companyList.map((d,idx) => companyList.map((d, idx) =>
<View className={`${styles.box} ${companyList.length-1 === idx && styles.noBorder} ` } onClick={async () => { <View className={`${styles.box} ${companyList.length - 1 === idx && styles.noBorder} `}
if(company?.id === d.id){ onClick={async () => {
return if (company?.id === d.id) return;
} Taro.showLoading({
Taro.showLoading({ title: '切换公司中',
title: '切换公司中', mask: true,
mask: true, })
}) const data = await userApi.companyReplace(d.id)
const data = await userApi.companyReplace(d.id) Taro.hideLoading()
Taro.hideLoading() !data && setCompany(d)
!data && setCompany(d) !data && Taro.showModal({
!data && Taro.showModal({ title: '友情提示',
title: '友情提示', content: '切换公司成功,需要重新进入',
content: '切换公司成功,需要重新进入', showCancel: false,
showCancel: false, success: function (res) {
success: function (res) { if (res.confirm) {
if (res.confirm) { Taro.reLaunch({url: '/pages/my/my'})
Taro.reLaunch({url: '/pages/my/my'}) }
} }
} })
}) setCompanyShow(false)
setCompanyShow(false) }}>
}}>
<View className={styles.image}> <View className={styles.image}>
<Img width={68} height={68} src={d.logo}/> <Img width={68} height={68} src={d.logo}/>
</View> </View>

Loading…
Cancel
Save