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. 57
      src/pages/business/userInfo/userInfo.tsx
  8. 2
      src/pages/business/videoInfo/videoInfo.tsx
  9. 23
      src/pages/index/components/videoList.tsx
  10. 2
      src/pages/index/index.tsx
  11. 35
      src/pages/my/components/header/header.tsx
  12. 20
      src/pages/my/components/header/service.tsx
  13. 33
      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 || '')
@ -50,12 +49,62 @@ const List = () => {
}) })
} }
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 !token && key === 'is_required'
&& key === 'is_required'
? <LoginView onSuccess={fetchData}/> : value?.length ? ? <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 {
companyList: Company[]
showCompany: () => void
}
const Header: FC<Props> = ({companyList, showCompany}) => {
const {token, user, company, empty} = Profile.useContainer() 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}/>:
<Image src={avatar} className={styles.avatar}/>
}
{ token ?
<View className='flex-1'>
<View className='font-32'>{user?.name}</View> <View className='font-32'>{user?.name}</View>
<View className='flex align-center mt-2' onClick={showCompany}>
<View className='flex align-center mt-2' onClick={()=>{
showCompany()
}}>
<Text style={{fontSize: '24rpx', fontWeight: '500', color: '#323635'}}>{company?.name}</Text> <Text style={{fontSize: '24rpx', fontWeight: '500', color: '#323635'}}>{company?.name}</Text>
<Image src={blacktriang} style={{width:'20rpx',height:'20rpx'}}></Image> {companyList.length > 2 && <Image src={blacktriang} style={{width: '20rpx', height: '20rpx'}}></Image>}
</View>
</View> </View>
</View>: : <View className='flex-1'>
<View className='flex-1'> <View className='font-32 mt-2' onClick={() => empty()}></View>
<View className='font-32 mt-2' onClick={()=>{
empty()
}}></View>
</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'
@ -31,20 +31,22 @@ const Service = () => {
} }
}) })
useEffect(() => { Taro.useDidShow(() => {
const oldList: List[] = JSON.parse(JSON.stringify(list))
if(token){
if ([1, 2].includes(user?.role_type || 0)) { if ([1, 2].includes(user?.role_type || 0)) {
oldList.unshift(...[ setList([
{title: '部门管理', src: dep, router: '/pages/manage/depAdmin/depAdmin'}, {title: '部门管理', src: dep, router: '/pages/manage/depAdmin/depAdmin'},
// {title: '课程市场', src: buy, router: '/pages/manage/curriculum/curriculum'},
{title: '现场会', src: spotMeeting, router: '/pages/manage/spotMeeting/spotMeeting'}, {title: '现场会', src: spotMeeting, router: '/pages/manage/spotMeeting/spotMeeting'},
{title: '课程管理', src: course, router: '/pages/manage/courseAdmin/courseAdmin'}, {title: '课程管理', src: course, router: '/pages/manage/courseAdmin/courseAdmin'},
{title: '个人中心', src: userInfo, router: '/pages/business/userInfo/userInfo'},
{title: '历史记录', src: cur, router: '/pages/business/history/history'},
])
} else {
setList([
{title: '历史记录', src: cur, router: '/pages/business/history/history'},
{title: '个人中心', src: userInfo, router: '/pages/business/userInfo/userInfo'},
]) ])
setList(oldList)
}
} }
}, []) })
function jump(url: string) { function jump(url: string) {
if (!token) { if (!token) {

@ -16,39 +16,38 @@ 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 {
userApi.companyList().then(res => {
setCompanyList(res as Company[]) 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/> <Time/>
<Service/> {token && <Service/>}
<PageContainer overlayStyle={'background:rgba(0,0,0,0.3)'} position={'bottom'} round={true} show={companyShow} <PageContainer
overlayStyle={'background:rgba(0,0,0,0.3)'}
position='bottom'
round
show={companyShow}
onClickOverlay={() => setCompanyShow(false)}> 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,

Loading…
Cancel
Save