main
king 1 year ago
parent ae9de5d810
commit b0cf7f4496
  1. 2
      src/components/lineChart/lineChart.module.scss
  2. 7
      src/components/lineChart/lineChart.tsx
  3. 2
      src/components/topic/topic.scss
  4. 3
      src/pages/business/curHistory/curHistory.config.ts
  5. 16
      src/pages/business/curHistory/curHistory.tsx
  6. 28
      src/pages/business/videoInfo/components/catalogue.tsx
  7. 2
      src/pages/business/videoInfo/components/hours.tsx
  8. 3
      src/pages/business/videoInfo/videoInfo.scss
  9. 4
      src/pages/manage/addCur/addCur.module.scss
  10. 4
      src/pages/manage/addCur/addCur.tsx
  11. 3
      src/pages/manage/addStudent/addStudent.scss
  12. 6
      src/pages/manage/addStudent/addStudent.tsx
  13. 11
      src/pages/manage/courseAdmin/components/search.tsx
  14. 8
      src/pages/manage/courseAdmin/courseAdmin.module.scss
  15. 5
      src/pages/manage/courseAdmin/courseAdmin.tsx
  16. 7
      src/pages/manage/selectDep/selectDep.tsx
  17. 2
      src/static/css/module.scss

@ -39,7 +39,7 @@
.line { .line {
width: 1rpx; width: 1rpx;
background: #ddd; background: #F2F8F6;
height: 100%; height: 100%;
margin-bottom: 10px; margin-bottom: 10px;
} }

@ -30,15 +30,14 @@ const LineChart: FC<Props> = ({data}) => {
return ( return (
<> <>
<ScrollView scrollX={!!maxHeight.value}> <ScrollView scrollX={!!maxHeight.value}>
<View style={{marginBottom: '30px'}}>{maxHeight.time}{formatMinute(maxHeight.value)}</View> <View style={{marginBottom: '30px'}}>{maxHeight.time}{formatMinute(maxHeight.value)}</View>
<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>{formatMinute(d.value)}</View>}
<View>{formatMinute(d.value)}</View>
<View className={style.column} style={{height: d.value / maxHeight.value * height + "px"}}> </View> <View className={style.column} style={{height: d.value / maxHeight.value * height + "px"}}> </View>
<View>{d.time}</View> <View>{d.time}</View>
</View> </View>

@ -9,7 +9,7 @@
background: #45D4A8; background: #45D4A8;
border-radius: 10rpx; border-radius: 10rpx;
color: #fff; color: #fff;
padding: 0 10rpx; padding: 3rpx 10rpx;
font-size: 26rpx; font-size: 26rpx;
margin-right: 20rpx; margin-right: 20rpx;
} }

@ -1,3 +1,4 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: '课程学习记录' navigationBarTitleText: '课程学习记录',
onReachBottomDistance: 30
}) })

@ -11,19 +11,33 @@ const CurHistory = () => {
const [show, setShow] = useState(false) const [show, setShow] = useState(false)
const {course_id} = Taro.getCurrentInstance().router?.params as unknown as { course_id: string } const {course_id} = Taro.getCurrentInstance().router?.params as unknown as { course_id: string }
const [data, setData] = useState<HourHistory[]>([]) const [data, setData] = useState<HourHistory[]>([])
const [DataAll, setDataAll] = useState<HourHistory[]>([])
const [course, setCourse] = useState<Curriculum | null>(null) const [course, setCourse] = useState<Curriculum | null>(null)
const [hours, setHours] = useState<Hour[] | null>(null) const [hours, setHours] = useState<Hour[] | null>(null)
const [durations, setDuration] = useState<Record<number, number> | null>(null) const [durations, setDuration] = useState<Record<number, number> | null>(null)
const [time, setTime] = useState<Record<number, { start: number, end: number }> | null>(null) const [time, setTime] = useState<Record<number, { start: number, end: number }> | null>(null)
const [page, setPage] = useState(1)
Taro.useLoad(() => { Taro.useLoad(() => {
userApi.courseRecord(course_id).then(res => { userApi.courseRecord(course_id).then(res => {
Taro.setNavigationBarTitle({title: res.course.title}) Taro.setNavigationBarTitle({title: res.course.title})
setData(Object.values(res.data)) setDataAll(Object.values(res.data))
setData(Object.values(res.data).slice(0, 10))
setCourse(res.course) setCourse(res.course)
}) })
}) })
Taro.useReachBottom(() => {
if (data.length < DataAll.length) {
const page_size = page * 10
setData([
...data,
...DataAll.slice(page_size, page_size + 10)
])
setPage(page + 1)
}
})
async function setHour(unique_ident: number) { async function setHour(unique_ident: number) {
try { try {
const res = await userApi.hourCourse(course_id, unique_ident) const res = await userApi.hourCourse(course_id, unique_ident)

@ -1,7 +1,7 @@
import {FC, useState} from "react"; import {FC, useState} from "react";
import Tabs, {OnChangOpt} from "@/components/tabs/tabs"; import Tabs, {OnChangOpt} from "@/components/tabs/tabs";
import {Image, View} from "@tarojs/components"; import {Image, View} from "@tarojs/components";
import {CourseDepData} from "@/api"; import {CourseDepData, curriculum} from "@/api";
import Collapse from "@/components/collapse/collapse"; import Collapse from "@/components/collapse/collapse";
import Hours from "@/pages/business/videoInfo/components/hours"; import Hours from "@/pages/business/videoInfo/components/hours";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
@ -95,6 +95,7 @@ const Catalogue: FC<Props> = ({data, setHors, id, playId}) => {
function learning() { function learning() {
const flats: Hour[] = Object.values(data?.hours || {}).flat(Infinity) as Hour[] const flats: Hour[] = Object.values(data?.hours || {}).flat(Infinity) as Hour[]
if ((data?.learn_hour_records?.length || undefined) == data?.learn_record?.hour_count && flats.length) { if ((data?.learn_hour_records?.length || undefined) == data?.learn_record?.hour_count && flats.length) {
if (flats[0].id === playId) { if (flats[0].id === playId) {
videoEvents.setVideoState('play') videoEvents.setVideoState('play')
@ -106,9 +107,28 @@ const Catalogue: FC<Props> = ({data, setHors, id, playId}) => {
if (data?.learn_hour_records.length) { if (data?.learn_hour_records.length) {
const lastTimeId = data.learn_hour_records[data.learn_hour_records.length - 1].id const lastHours = data.learn_hour_records[data.learn_hour_records.length - 1]
if (lastHours.courseHourRecordsFinish < 1) {
Taro.showModal({
title: '考卷未完成,是否前往',
content: '考卷未完成不能播放下一个视频',
confirmText: '前往考试',
cancelText: '观看视频',
async success({confirm}) {
if (confirm) {
const {hour_test} = await curriculum.hourPlay(lastHours.course_id, lastHours.id)
Taro.navigateTo({url: `/pages/business/test/test?testId=${hour_test?.id}`})
} else {
setHors(true, lastHours.id)
}
}
})
return;
}
for (const [index, flat] of flats.entries()) { for (const [index, flat] of flats.entries()) {
if (flat.id === lastTimeId) { if (flat.id === lastHours.id) {
const next = flats[index + 1] const next = flats[index + 1]
if (next) { if (next) {
if (next.id === playId) { if (next.id === playId) {
@ -119,8 +139,6 @@ const Catalogue: FC<Props> = ({data, setHors, id, playId}) => {
} }
} }
} }
} else {
Taro.showToast({title: "无播放视频", icon: 'error'})
} }
} }

@ -77,7 +77,7 @@ const Hours: FC<Props> = ({data, click, learn_hour_records, playId}) => {
{complete(d.id) === 0 && <View className='font-26 text-danger'></View>} {complete(d.id) === 0 && <View className='font-26 text-danger'></View>}
</View> </View>
{ {
complete(data?.[index - 1]?.id) == null complete(data?.[index - 1]?.id) !== 1
&& index !== 0 && index !== 0
&& <Image className='lock' src={lock} mode='aspectFit'/> && <Image className='lock' src={lock} mode='aspectFit'/>
} }

@ -54,7 +54,7 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
box-sizing: border-box; box-sizing: border-box;
border-bottom: 1px solid #ddd; border-bottom: 1px solid #F5F8F7;
.text { .text {
width: 600rpx; width: 600rpx;
@ -63,6 +63,7 @@
.lock { .lock {
width: 30rpx; width: 30rpx;
height: 30rpx;
margin-left: 10rpx; margin-left: 10rpx;
margin-top: 10rpx; margin-top: 10rpx;
} }

@ -1,7 +1,7 @@
.curBox { .curBox {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 30rpx 0; padding: 30rpx 20rpx;
width: 100%; width: 100%;
border-bottom: 1px solid #F5F8F7; border-bottom: 1px solid #F5F8F7;
} }
@ -15,7 +15,7 @@
.fixed { .fixed {
position: fixed; position: fixed;
bottom: 0; bottom: env(safe-area-inset-bottom);
left: 0; left: 0;
background: #f1f8f6; background: #f1f8f6;
width: 100%; width: 100%;

@ -87,9 +87,9 @@ const AddCur: FC = () => {
<View className='flex flex-wrap bg-white'> <View className='flex flex-wrap bg-white'>
{data?.map((d) => {data?.map((d) =>
<View key={d.id} className={styles.curBox} onClick={() => addCur(d.id)}> <View key={d.id} className={styles.curBox} onClick={() => addCur(d.id)}>
<Radio checked={courseId.includes(d.id)} onClick={() => addCur(d.id)}/> <Radio checked={courseId.includes(d.id)} onClick={() => addCur(d.id)} color='#45d4a8'/>
<View className='flex'> <View className='flex'>
<Image src={d.thumb} className={styles.image}/> <Image fadeIn lazyLoad src={d.thumb} className={styles.image}/>
<View>{d.title}</View> <View>{d.title}</View>
</View> </View>
</View> </View>

@ -12,6 +12,5 @@
.add { .add {
position: fixed; position: fixed;
width: 710rpx; width: 710rpx;
bottom: env(safe-area-inset-bottom); margin-top: 10px;
margin-bottom: 30px;
} }

@ -90,7 +90,7 @@ const AddStudent = () => {
}) })
return ( return (
<View className='bg-white px-2'> <View className='bg-white px-2 mt-2'>
<Form className='form' onSubmit={submit}> <Form className='form' onSubmit={submit}>
<View className='item'> <View className='item'>
<View></View> <View></View>
@ -113,13 +113,13 @@ const AddStudent = () => {
<View></View> <View></View>
<View className='flex align-center' onClick={jumSetDep}> <View className='flex align-center' onClick={jumSetDep}>
<View> <View>
{depIds.length ? formatDep() : '选择'} {depIds.length ? formatDep() : '选择部门'}
</View> </View>
<Icon name='chevron-right'/> <Icon name='chevron-right'/>
</View> </View>
</View> </View>
<Button className='add button' formType='submit'>{params.id ? '修改' : "新建"}</Button> <Button className='add button' formType='submit'>{params.id ? '修改学员' : "添加学员"}</Button>
</Form> </Form>
</View> </View>
) )

@ -70,10 +70,19 @@ export const Search: FC<Props> = ({param, setParam}) => {
<View onClick={() => setShow(true)}> <View onClick={() => setShow(true)}>
<Text></Text> <Text></Text>
<Image src={screen} <Image src={screen}
style={{display: 'inline-block', width: '15px', verticalAlign: 'middle', marginLeft: '5px'}}/> mode='aspectFit'
style={{
display: 'inline-block',
width: '15px',
height: '15px',
verticalAlign: 'middle',
marginLeft: '5px'
}}/>
</View> </View>
</View> </View>
{param.dep_id > 0 && <View className='mt-2'>{deps.find(d => d.id === param.dep_id)?.name}</View>}
<CustomPageContainer show={show} position='top' onClickOverlay={() => setShow(false)}> <CustomPageContainer show={show} position='top' onClickOverlay={() => setShow(false)}>
<View className={styles.custom}> <View className={styles.custom}>
{deps.length ? {deps.length ?

@ -3,7 +3,6 @@
padding: 24rpx 30rpx; padding: 24rpx 30rpx;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: top;
} }
.searchInput { .searchInput {
@ -44,7 +43,7 @@
width: 280rpx; width: 280rpx;
height: 164rpx; height: 164rpx;
border-radius: 10rpx; border-radius: 10rpx;
margin: 0 20px; margin: 0 20px 0 0;
background: #eee; background: #eee;
} }
@ -52,13 +51,14 @@
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
taro-view-core { taro-view-core,
View {
padding: 20rpx 0; padding: 20rpx 0;
flex: 1; flex: 1;
width: 100%; width: 100%;
text-align: center; text-align: center;
&:last-child{ &:last-child {
border: 1px solid #F5F8F7; border: 1px solid #F5F8F7;
} }
} }

@ -72,6 +72,7 @@ const CourseAdmin: FC = () => {
Taro.showModal({ Taro.showModal({
title: '删除警告', title: '删除警告',
content: "删除后所有部门不可查看", content: "删除后所有部门不可查看",
confirmText:'删除',
async success({confirm}) { async success({confirm}) {
if (confirm) { if (confirm) {
try { try {
@ -173,13 +174,13 @@ const CourseAdmin: FC = () => {
{ {
!batch !batch
&& data.length > 0 && data.length > 0
&& <View style={{margin: 'auto', padding: '15px'}} onClick={() => setBatch(true)}></View> && <View style={{margin: 'auto', padding: '15px'}} onClick={() => setBatch(true)}></View>
} }
{ {
batch && <View className={styles.addBatch}> batch && <View className={styles.addBatch}>
<Radio onClick={all} checked={data.length === curs.length}> </Radio> <Radio onClick={all} checked={data.length === curs.length}> </Radio>
<Text onClick={() => setBatch(false)}></Text> <Text onClick={() => setBatch(false)}></Text>
<MyButton size='mini' onClick={() => batchChangDep(curs)}>{curs.length}</MyButton> <MyButton size='mini' onClick={() => batchChangDep(curs)}>{curs.length}</MyButton>
</View> </View>
} }
</View> </View>

@ -50,10 +50,6 @@ const SelectDep: FC = () => {
}, [ids]) }, [ids])
function ok() { function ok() {
if (!ids.length) {
Taro.showToast({title: '请选择部门', icon: "error"})
return
}
storageDep.set(ids) storageDep.set(ids)
storageDep.setRequired(required) storageDep.setRequired(required)
Taro.navigateBack({delta: 1}) Taro.navigateBack({delta: 1})
@ -84,7 +80,7 @@ const SelectDep: FC = () => {
return ( return (
<View className='px-2 bg-white'> <View className='px-2 bg-white'>
{deps.map((d) => <View className='flex align-center' key={d.id} onClick={() => onChange(d.id)}> {deps.map((d) => <View className='flex align-center' key={d.id} onClick={() => onChange(d.id)}>
<Checkbox value={d.id + ''} checked={ids.includes(d.id)}/> <Checkbox value={d.id + ''} checked={ids.includes(d.id)} color='#45d4a8'/>
<View style={{flex: 1}}> <View style={{flex: 1}}>
<PopPut <PopPut
key={d.id} key={d.id}
@ -95,6 +91,7 @@ const SelectDep: FC = () => {
params?.required ? params?.required ?
<View className='flex align-center'> <View className='flex align-center'>
<Switch <Switch
color='#45d4a8'
onClick={() => event?.stopImmediatePropagation()} onClick={() => event?.stopImmediatePropagation()}
checked={isRequired(d.id)} checked={isRequired(d.id)}
onChange={(e) => requiredChange(d.id, e.detail.value)}/> onChange={(e) => requiredChange(d.id, e.detail.value)}/>

@ -32,7 +32,7 @@ taro-button-core::after {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
border-bottom: 1px solid #ddd; border-bottom: 1px solid #F5F8F7;
height: 80px; height: 80px;
} }

Loading…
Cancel
Save