解决不正当操作流程

main
king 2 years ago
parent 38dd48c99e
commit dc1a72ce9a
  1. 4
      src/api/manage.ts
  2. 16
      src/api/user.ts
  3. 16
      src/components/lineChart/lineChart.module.scss
  4. 42
      src/components/lineChart/lineChart.tsx
  5. 11
      src/components/video/video.tsx
  6. 35
      src/pages/business/history/components/CategoryTabs.tsx
  7. 32
      src/pages/business/history/history.tsx
  8. 11
      src/pages/business/videoInfo/components/course.tsx
  9. 27
      src/pages/business/videoInfo/videoInfo.tsx
  10. 79
      src/pages/manage/addCur/addCur.tsx
  11. 10
      src/pages/manage/addStudent/addStudent.tsx
  12. 2
      src/pages/manage/depAdmin/depAdmin.tsx
  13. 2
      src/pages/manage/depCur/depCur.module.scss
  14. 9
      src/pages/manage/depCur/depCur.tsx
  15. 3
      src/pages/manage/meetings/meetings.tsx
  16. 18
      src/pages/manage/selectDep/selectDep.tsx
  17. 7
      src/pages/manage/spotMeeting/spotMeeting.tsx
  18. 19
      src/pages/manage/userInfo/userInfo.tsx
  19. 29
      types/user.d.ts

@ -105,8 +105,8 @@ export const ManageApi = {
return request<DepCurData>(`/api/v1/department/${data.id}/courses?page=${data.page}&size=${data.size}`, "GET") return request<DepCurData>(`/api/v1/department/${data.id}/courses?page=${data.page}&size=${data.size}`, "GET")
}, },
/** 未添加课程 */ /** 未添加课程 */
optionalCur(dep_id: number, category_id: number) { optionalCur(dep_id: number) {
return request<Curriculum[]>(`/api/v1/department/${dep_id}/optional?category_id=${category_id}`, "GET") return request<Curriculum[]>(`/api/v1//choose/${dep_id}/index`, "GET")
}, },
addCur(data: AddCurProps) { addCur(data: AddCurProps) {
return request('/api/v1/course/user', "POST", data) return request('/api/v1/course/user', "POST", data)

@ -26,10 +26,6 @@ interface CheckoutData {
company: Company company: Company
} }
interface DepListData {
departments: Department[]
user: User
}
interface LearningRecord { interface LearningRecord {
user_course_records: LearnRecord[] user_course_records: LearnRecord[]
@ -64,10 +60,6 @@ export const userApi = {
putName(id: number, name: string) { putName(id: number, name: string) {
return request<User>(`/api/v1/auth/login/${id}`, "PUT", {name}) return request<User>(`/api/v1/auth/login/${id}`, "PUT", {name})
}, },
/** 所属部门 */
depList() {
return request<DepListData>(`/api/v1/user/detail`, "GET")
},
code(catch_key: string) { code(catch_key: string) {
return request<{ code: Code }>(`/api/v1/auth/login/code`, "POST", {openid: catch_key}) return request<{ code: Code }>(`/api/v1/auth/login/code`, "POST", {openid: catch_key})
}, },
@ -75,8 +67,8 @@ export const userApi = {
return request<LearningRecord>(`/api/v1/user/record/course`, "GET", courseId ? {courseId} : {}) return request<LearningRecord>(`/api/v1/user/record/course`, "GET", courseId ? {courseId} : {})
}, },
/** 学习记录 */ /** 学习记录 */
record(category_id: number) { record() {
return request<Record<number, HourHistory>>(`/api/v1/course/${category_id}/record`, "GET") return request<{course:HourHistory[],durations:Record<number, number>}>(`/api/v1/category/history`, "GET")
}, },
courseRecord(course_id: string) { courseRecord(course_id: string) {
return request<CourseRecord>(`/api/v1/course/${course_id}/info`, "GET") return request<CourseRecord>(`/api/v1/course/${course_id}/info`, "GET")
@ -92,6 +84,8 @@ export const userApi = {
}, },
/**获取指定学员指定时间学习记录 */ /**获取指定学员指定时间学习记录 */
statistics(user_id: string, data: StatisticsParam) { statistics(user_id: string, data: StatisticsParam) {
return request<{data:Record<number, number>}>(`/api/v1/statistics/statistics/${user_id}?start_time=${data.start_time}&end_time=${data.end_time}`, "GET") return request<{
data: Record<number, number>
}>(`/api/v1/statistics/statistics/${user_id}?start_time=${data.start_time}&end_time=${data.end_time}`, "GET")
} }
} }

@ -4,6 +4,22 @@
justify-content: left; justify-content: left;
flex-wrap: nowrap; flex-wrap: nowrap;
height: 420px; height: 420px;
position: relative;
margin-top: 30rpx;
}
.empty {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: 10rpx;
color: #00D6AC;
display: flex;
justify-content: center;
align-items: center;
background: rgba(#fff, .9);
} }
.columnBox { .columnBox {

@ -13,31 +13,39 @@ interface Props {
const height = 180 const height = 180
const LineChart: FC<Props> = ({data}) => { const LineChart: FC<Props> = ({data}) => {
const [maxHeight, setMaxHeight] = useState(0) const [maxHeight, setMaxHeight] = useState<lineData>({time: '', value: 0})
const [lineChartList, setLineChartList] = useState(data) const [lineChartList, setLineChartList] = useState(data)
useEffect(() => { useEffect(() => {
setLineChartList(data) setLineChartList(data)
setMaxHeight(data.reduce((pre, cur) => { setMaxHeight(data.reduce((pre, cur) => {
return Math.max(pre, cur.value) if (cur.value > pre.value) {
}, 0)) return cur
}
return pre
}, maxHeight))
}, [data]) }, [data])
return ( return (
<ScrollView scrollX> <>
<View className={style.lineChart}> <ScrollView scrollX={!!maxHeight.value}>
{ <View>{maxHeight.time}{maxHeight.value}</View>
lineChartList.map(d => <View key={d.time}> <View className={style.lineChart}>
<View className={style.columnBox} style={{width: "100px"}}> {!maxHeight.value && <View className={style.empty}></View>}
<View className={style.line} style={{height: height - 10 - (d.value / maxHeight * height) + "px"}}></View> {
<View>{d.value}</View> lineChartList.map(d => <View key={d.time}>
<View className={style.column} style={{height: d.value / maxHeight * height + "px"}}> </View> <View className={style.columnBox} style={{width: "100px"}}>
<View>{d.time}</View> <View className={style.line}
</View> style={{height: height - 10 - (d.value / maxHeight.value * height) + "px"}}></View>
</View>) <View>{d.value}</View>
} <View className={style.column} style={{height: d.value / maxHeight.value * height + "px"}}> </View>
</View> <View>{d.time}</View>
</ScrollView> </View>
</View>)
}
</View>
</ScrollView>
</>
) )
} }

@ -13,7 +13,8 @@ const HVideo: FC<HVideoOptions> = (opt: HVideoOptions) => {
try { try {
video = Taro.createVideoContext('myVideo') video = Taro.createVideoContext('myVideo')
} catch (e) {} } catch (e) {
}
function onTimeUpdate(event: BaseEventOrig<VideoProps.onTimeUpdateEventDetail>) { function onTimeUpdate(event: BaseEventOrig<VideoProps.onTimeUpdateEventDetail>) {
// if (opt.preview) return; // if (opt.preview) return;
@ -57,10 +58,12 @@ const HVideo: FC<HVideoOptions> = (opt: HVideoOptions) => {
unique_ident.put(Number(currentTime.toFixed(2)), Date.now()) unique_ident.put(Number(currentTime.toFixed(2)), Date.now())
}) })
Taro.useDidShow(()=>{ Taro.useDidShow(() => {
if(!video){ if (!video) {
video = Taro.createVideoContext('myVideo') video = Taro.createVideoContext('myVideo')
video.play() if (currentTime && currentTime < opt.duration - deviation) {
video.play()
}
} }
}) })

@ -1,35 +0,0 @@
import {FC, useState} from "react";
import {View} from "@tarojs/components";
import {publicApi} from "@/api/public";
import Taro from "@tarojs/taro";
import Tabs, {OnChangOpt, TabList} from "@/components/tabs/tabs";
interface Props {
changeTabs: (id: number) => void
}
const CategoryTabs: FC<Props> = ({changeTabs}) => {
const [tabs, setTabs] = useState<TabList[]>([])
async function getData() {
const res = await publicApi.category()
const data = Object.values(res.categories).reduce((pre, cur) => {
pre.push(...cur)
return pre
}, []).map<TabList>(d => ({title: d.name, value: d.id}))
setTabs(data)
changeTabs(data[0].value as number)
}
function onChange(data: OnChangOpt) {
changeTabs(data.tab?.value as number)
}
Taro.useLoad(getData)
return (
<View className='bg-white'>
<Tabs tabList={tabs} onChange={onChange}/>
</View>
)
}
export default CategoryTabs

@ -1,40 +1,44 @@
import {Image, Text, View} from "@tarojs/components"; import {Image, Text, View} from "@tarojs/components";
import CategoryTabs from "@/pages/business/history/components/CategoryTabs";
import styles from './history.module.scss' import styles from './history.module.scss'
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import {userApi} from "@/api"; import {useEffect, useState} from "react";
import {useState} from "react";
import {formatMinute} from "@/utils/time"; import {formatMinute} from "@/utils/time";
import Empty from "@/components/empty/empty"; import Empty from "@/components/empty/empty";
import {userApi} from "@/api";
const History = () => { const History = () => {
const [data, setData] = useState<HourHistory[]>([]) const [data, setData] = useState<HourHistory[]>([])
const [durations, setDurations] = useState<Record<number, number>>({})
async function getData(id: number) { async function getData() {
const res = await userApi.record(id) const res = await userApi.record()
setData(Object.values(res)) setData(res.course)
setDurations(res.durations)
} }
function jump(course_id: number) { function jump(course_id: number) {
Taro.navigateTo({url: `/pages/business/curHistory/curHistory?course_id=${course_id}`}) Taro.navigateTo({url: `/pages/business/curHistory/curHistory?course_id=${course_id}`})
} }
useEffect(() => {
getData()
}, [])
return ( return (
<View> <View>
<CategoryTabs changeTabs={getData}/>
<View className='mt-3'> <View className='mt-3'>
{data.length ? data.map((d, index) => {data.length ? data.map((d, index) =>
<View key={index} className={styles.category} onClick={() => jump(d.course_id)}> <View key={index} className={styles.category} onClick={() => jump(d.userCourseRecord.course_id)}>
<View className={styles.thumb}> <View className={styles.thumb}>
<Image src={d.course.thumb} className={styles.image}/> <Image src={d.thumb} className={styles.image}/>
<View className={styles.count}>{d.total_hour_count}/{d.finished_count}</View> <View
className={styles.count}>{d.userCourseRecord.hour_count}/{d.userCourseRecord.finished_count}</View>
</View> </View>
<View className={styles.text}> <View className={styles.text}>
<View>{d.course.title}</View> <View>{d.title}</View>
<View className={styles.describe}> <View className={styles.describe}>
<Text className='mr-4'>{formatMinute(d.duration)}</Text> <Text className='mr-4'>{formatMinute(durations[d.id])}</Text>
<Text>{(d.finished_count / d.total_hour_count * 100).toFixed(0)}%</Text> <Text>{(d.userCourseRecord.finished_count / d.userCourseRecord.hour_count * 100).toFixed(0)}%</Text>
</View> </View>
</View> </View>
</View>) : <Empty name='无观看记录'/>} </View>) : <Empty name='无观看记录'/>}

@ -107,14 +107,7 @@ const Course: FC<Props> = ({id, courseId, preview, curEnd}: Props) => {
setValidate(false) setValidate(false)
setNewRecord([]) setNewRecord([])
setTime(0) setTime(0)
setIndex(0)
if (process.env.TARO_ENV === 'h5') {
setTimeout(() => {
setIndex(0)
}, 200)
} else {
setIndex(0)
}
} }
/** 再来一次 */ /** 再来一次 */
@ -219,7 +212,7 @@ const Course: FC<Props> = ({id, courseId, preview, curEnd}: Props) => {
style={{height: "60vh"}} style={{height: "60vh"}}
snapToEdge snapToEdge
current={index} current={index}
onChange={(e) => setIndex(e.detail.current)}> onChange={(e) => setIndex(e.detail.current ?? index)}>
{examAll?.[time]?.map((d) => {examAll?.[time]?.map((d) =>
<SwiperItem key={d.id}> <SwiperItem key={d.id}>
<ScrollView style='height:70vh' scrollY> <ScrollView style='height:70vh' scrollY>

@ -7,6 +7,7 @@ import Course from "./components/course";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import eventsIndex from "@/hooks/eventsIndex"; import eventsIndex from "@/hooks/eventsIndex";
import {formatMinute} from "@/utils/time"; import {formatMinute} from "@/utils/time";
import unique_ident from "@/hooks/unique_ident";
const VideoInfo: FC = () => { const VideoInfo: FC = () => {
const {id, depId} = Taro.getCurrentInstance()?.router?.params as any const {id, depId} = Taro.getCurrentInstance()?.router?.params as any
@ -15,20 +16,20 @@ const VideoInfo: FC = () => {
const [preview, setPreview] = useState(false) const [preview, setPreview] = useState(false)
const [playing, setPlaying] = useState(false) const [playing, setPlaying] = useState(false)
const getData = useCallback(async () => { const getData = useCallback(async (playing: boolean) => {
const res = await curriculum.courseDep(id, depId) const res = await curriculum.courseDep(id, depId)
if (res) { if (res) {
setData(res) setData(res)
} }
if (playId) { // 用于自动播放 判断当前课程是否完成 if (playId != null) { // 用于自动播放 判断当前课程是否完成
currentVideo(res) currentVideo(res, playing)
} }
}, [playing]) }, [playing, playId])
const curEnd = useCallback(() => { const curEnd = () => {
setPlaying(false) setPlaying(false)
getData().then() getData(false).then()
}, [data, playing, playId]) }
function setHors(is_complete: boolean, play_id: number) { function setHors(is_complete: boolean, play_id: number) {
setPlaying(true) setPlaying(true)
@ -37,7 +38,7 @@ const VideoInfo: FC = () => {
} }
useEffect(() => { useEffect(() => {
getData() getData(false)
}, [id]) }, [id])
@ -71,7 +72,7 @@ const VideoInfo: FC = () => {
/** /**
* *
*/ */
const currentVideo = useCallback((data: CourseDepData) => { const currentVideo = useCallback((data: CourseDepData, playing: boolean) => {
const courseHourRecordsFinish = data?.learn_hour_records.find(d => d.id === playId)?.courseHourRecordsFinish const courseHourRecordsFinish = data?.learn_hour_records.find(d => d.id === playId)?.courseHourRecordsFinish
if (typeof courseHourRecordsFinish === 'number') { if (typeof courseHourRecordsFinish === 'number') {
if (courseHourRecordsFinish === 1) { if (courseHourRecordsFinish === 1) {
@ -89,12 +90,16 @@ const VideoInfo: FC = () => {
}) })
} }
} }
}, [playId, data]) }, [playId, data, playing])
Taro.useDidShow(() => { Taro.useDidShow(() => {
data && getData() data && getData(playing)
}) })
Taro.useUnload(() => {
unique_ident.del()
})
return ( return (
<> <>
<View className='content'> <View className='content'>

@ -1,9 +1,7 @@
import {CustomWrapper, View} from "@tarojs/components"; import {View} from "@tarojs/components";
import {getCurrentInstance} from "@tarojs/runtime"; import {getCurrentInstance} from "@tarojs/runtime";
import {ManageApi} from "@/api/manage"; import {ManageApi} from "@/api/manage";
import React, {FC, useEffect, useState} from "react"; import React, {FC, useEffect, useState} from "react";
import Tabs, {TabList} from "@/components/tabs/tabs";
import {Category, publicApi} from "@/api/public";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import VideoCover from "@/components/videoCover/videoCover"; import VideoCover from "@/components/videoCover/videoCover";
import Empty from "@/components/empty/empty"; import Empty from "@/components/empty/empty";
@ -16,50 +14,24 @@ interface AddProps {
const AddCur = () => { const AddCur = () => {
const {id} = getCurrentInstance()?.router?.params as { id: string } const {id} = getCurrentInstance()?.router?.params as { id: string }
const [category, setCategory] = useState<TabList[]>([]) const [data, setData] = useState<Curriculum[]>([])
const [categoryId, setCategoryId] = useState<number>(0)
const [dataMap, setDataMap] = useState<Map<number, Curriculum[]>>(new Map())
async function getCategory() { async function getData() {
try { try {
const data: (TabList)[] = [] const res = await ManageApi.optionalCur(Number(id))
const {categories} = await publicApi.category() if (res.length) {
Object.values(categories).map(d => { setData(res)
data.push(...d.map<TabList<Category>>(c => ({title: c.name, value: c.id}))) }
})
setCategory(data)
setCategoryId(data[0].value as number)
} catch (e) { } catch (e) {
}
}
async function getData() {
if (categoryId !== null) {
const res = await ManageApi.optionalCur(Number(id), categoryId)
const map = new Map(dataMap)
const data = map.get(categoryId)
if (!data) {
map.delete(categoryId)
map.set(categoryId, res)
setDataMap(map)
} else {
res.forEach(d => {
const index = data.findIndex(c => c.id === d.id)
if (index === -1) {
data.push(d)
} else {
data.splice(index, 1, d)
}
})
map.delete(categoryId)
map.set(categoryId, data)
setDataMap(map)
}
} }
} }
useEffect(() => {
getData()
}, [])
const Add: FC<AddProps> = ({cur_id, name, index}) => { const Add: FC<AddProps> = ({cur_id, name, index}) => {
function addCur() { function addCur() {
Taro.showModal({ Taro.showModal({
@ -71,14 +43,9 @@ const AddCur = () => {
const is_required = confirm ? 1 : 0 const is_required = confirm ? 1 : 0
Taro.showLoading() Taro.showLoading()
await ManageApi.addCur({course_id: [cur_id], dep_id: [Number(id)], is_required}) await ManageApi.addCur({course_id: [cur_id], dep_id: [Number(id)], is_required})
const map = new Map(dataMap) const oldData: Curriculum[] = JSON.parse(JSON.stringify(data))
const data = map.get(categoryId!) || [] oldData.splice(index, 1)
if (data) { setData(oldData)
data.splice(index, 1)
}
map.delete(categoryId!)
map.set(categoryId!, data)
setDataMap(map)
Taro.showToast({title: "添加成功"}) Taro.showToast({title: "添加成功"})
} catch (e) { } catch (e) {
} }
@ -92,22 +59,12 @@ const AddCur = () => {
) )
} }
useEffect(() => {
getCategory().then()
}, [])
useEffect(() => {
getData().then()
}, [categoryId])
return ( return (
<CustomWrapper> <>
<View className='bg-white'>
<Tabs tabList={category} onChange={(data) => setCategoryId(data.tab?.value as number)} current={categoryId}/>
</View>
{ {
(categoryId && dataMap.get(categoryId)?.length) ? data.length ?
<View className='bg-white mt-2 py-2 flex flex-wrap'> <View className='bg-white mt-2 py-2 flex flex-wrap'>
{dataMap.get(categoryId)?.map((d, index) => ( {data?.map((d, index) => (
<VideoCover <VideoCover
key={d.id} key={d.id}
thumb={d.thumb} thumb={d.thumb}
@ -120,7 +77,7 @@ const AddCur = () => {
</View> </View>
: <Empty name='无更多课程'/> : <Empty name='无更多课程'/>
} }
</CustomWrapper> </>
) )
} }

@ -37,6 +37,12 @@ const AddStudent = () => {
return return
} }
} }
if (!depIds.length) {
Taro.showToast({title: "请选择部门", icon: 'error'})
return
}
Taro.showLoading() Taro.showLoading()
try { try {
if (params.id) { if (params.id) {
@ -80,7 +86,7 @@ const AddStudent = () => {
Taro.useDidShow(() => { Taro.useDidShow(() => {
const newDepIds = storageDep.get() const newDepIds = storageDep.get()
setDepIds( newDepIds.length ?newDepIds: depIds) setDepIds(newDepIds.length ? newDepIds : depIds)
}) })
return ( return (
@ -113,7 +119,7 @@ const AddStudent = () => {
</View> </View>
</View> </View>
<Button className='add button' formType='submit'></Button> <Button className='add button' formType='submit'>{params.id ? '修改' : "新建"}</Button>
</Form> </Form>
</View> </View>
) )

@ -109,6 +109,7 @@ const DepAdmin: FC = () => {
sort: manages.length, sort: manages.length,
}) })
} }
getData()
setShow(false) setShow(false)
} catch (e) { } catch (e) {
Taro.showToast({title: '操作失败', icon: 'error'}) Taro.showToast({title: '操作失败', icon: 'error'})
@ -131,7 +132,6 @@ const DepAdmin: FC = () => {
return ( return (
<> <>
<View> <View>
{manages.map(d => <PopPut {manages.map(d => <PopPut
key={d.id} key={d.id}
title={d.name} title={d.name}

@ -21,7 +21,7 @@
border-radius: 10rpx; border-radius: 10rpx;
margin-right: 10rpx; margin-right: 10rpx;
width: 280rpx; width: 280rpx;
height: 150rpx; height: 180rpx;
} }
.del { .del {

@ -1,7 +1,7 @@
import {getCurrentInstance} from "@tarojs/runtime"; import {getCurrentInstance} from "@tarojs/runtime";
import Taro, {useReachBottom} from "@tarojs/taro"; import Taro, {useReachBottom} from "@tarojs/taro";
import {ManageApi} from "@/api/manage"; import {ManageApi} from "@/api/manage";
import React, {FC, useState} from "react"; import React, {FC, useEffect, useState} from "react";
import {Image, View} from "@tarojs/components"; import {Image, View} from "@tarojs/components";
import {curriculum} from "@/api"; import {curriculum} from "@/api";
import MyButton from "@/components/button/MyButton"; import MyButton from "@/components/button/MyButton";
@ -68,7 +68,10 @@ const DepCur: FC = () => {
Taro.navigateTo({url: "/pages/manage/addCur/addCur?id=" + id}) Taro.navigateTo({url: "/pages/manage/addCur/addCur?id=" + id})
} }
Taro.useDidShow(() => getData()) useEffect(() => {
getData()
}, [])
useReachBottom(() => { useReachBottom(() => {
if (data.length < total) { if (data.length < total) {
getData(true) getData(true)
@ -79,7 +82,7 @@ const DepCur: FC = () => {
<View className={styles.page}> <View className={styles.page}>
{ {
data.length ? data.length ?
data.map(d => <View className={styles.curBox}> data.map(d => <View key={d.id} className={styles.curBox}>
<View className={styles.imageBox}> <View className={styles.imageBox}>
<Image src={d.thumb} className={styles.image} mode='aspectFill'/> <Image src={d.thumb} className={styles.image} mode='aspectFill'/>
<View>{d.title}</View> <View>{d.title}</View>

@ -61,10 +61,9 @@ const MeetingsConfig: FC = () => {
{ {
meeting.length ? meeting.length ?
meeting.map((d, index) => <View className={styles.meeting} key={d.id}> meeting.map((d, index) => <View className={styles.meeting} key={d.id}>
<View className={styles.title} onClick={() => jumpInfo(d.id)}> <View className={styles.title} onClick={() => Date.now() < d.estimate_end_time && jumpInfo(d.id)}>
<View className='font-weight mb-1'>{d.name}</View> <View className='font-weight mb-1'>{d.name}</View>
<View>{formatDate(new Date(d.estimate_start_time), "MM-dd")} {formatDate(new Date(d.estimate_start_time), "MM-dd")}</View> <View>{formatDate(new Date(d.estimate_start_time), "MM-dd")} {formatDate(new Date(d.estimate_start_time), "MM-dd")}</View>
{Date.now() > d.estimate_end_time && <View className={styles.overdue}></View>} {Date.now() > d.estimate_end_time && <View className={styles.overdue}></View>}
</View> </View>
<View className={styles.del} onClick={() => del(d.id, index)}></View> <View className={styles.del} onClick={() => del(d.id, index)}></View>

@ -16,15 +16,21 @@ const SelectDep: FC = () => {
curriculum.department().then(res => { curriculum.department().then(res => {
setDeps(res.data) setDeps(res.data)
}) })
setIds(JSON.parse(depIds)) setIds(JSON.parse(depIds))
}, []) }, [])
const onChange = useCallback((id: number) => { const onChange = useCallback((id: number) => {
setIds([ const index = ids.indexOf(id)
...ids, if (index === -1) {
id setIds([
]) ...ids,
id
])
} else {
const oldIds: number[] = JSON.parse(JSON.stringify(ids))
oldIds.splice(index, 1)
setIds(oldIds)
}
}, [ids]) }, [ids])
function ok() { function ok() {
@ -38,7 +44,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)}/>
<PopPut <PopPut
key={d.id} key={d.id}

@ -13,8 +13,8 @@ const SpotMeeting: FC = () => {
const path = encodeURIComponent("/pages/meeting/meeting") const path = encodeURIComponent("/pages/meeting/meeting")
const params = Taro.getCurrentInstance().router?.params as { id: string | undefined } const params = Taro.getCurrentInstance().router?.params as { id: string | undefined }
const [manages, setManages] = useState<Manage[]>([]) const [manages, setManages] = useState<Manage[]>([])
const [start, setStart] = useState<string>(formatDate(new Date(), "YY-MM-dd hh:00:00")) const [start, setStart] = useState<string>(formatDate(new Date(new Date().getTime() + 24 * 60 * 60 * 1000), "YY-MM-dd hh:00:00"))
const [end, setEnd] = useState<string>(formatDate(new Date(), "YY-MM-dd 18:00:00")) const [end, setEnd] = useState<string>(formatDate(new Date(new Date().getTime() + 24 * 60 * 60 * 1000), "YY-MM-dd 18:00:00"))
const [depid, setDepid] = useState<number | null>(null) const [depid, setDepid] = useState<number | null>(null)
const [imgUrl, setImgUrl] = useState('') const [imgUrl, setImgUrl] = useState('')
const [name, setName] = useState('') const [name, setName] = useState('')
@ -277,7 +277,8 @@ const SpotMeeting: FC = () => {
</Form> </Form>
</View> </View>
{!params.id && <View className='text-center text-muted my-3' onClick={jumpMeetings}> <Icon name='chevron-right'/></View>} {!params.id && <View className='text-center text-muted my-3' onClick={jumpMeetings}> <Icon
name='chevron-right'/></View>}
</View> </View>
</View> </View>

@ -37,6 +37,7 @@ const UserInfo: FC = () => {
const {userId} = Taro.getCurrentInstance().router?.params as { userId: string } const {userId} = Taro.getCurrentInstance().router?.params as { userId: string }
const [data, setData] = useState<User | null>(null) const [data, setData] = useState<User | null>(null)
const [lineData, setLineData] = useState<any[]>([]) const [lineData, setLineData] = useState<any[]>([])
const router = Taro.useRouter()
const {user} = Profile.useContainer() const {user} = Profile.useContainer()
function setRoleType() { function setRoleType() {
@ -69,9 +70,11 @@ const UserInfo: FC = () => {
title: '是否确认删除', title: '是否确认删除',
async success({confirm}) { async success({confirm}) {
if (confirm) { if (confirm) {
await ManageApi.del(userId) try {
Taro.showToast({title: '删除成功'}) await ManageApi.del(userId)
Taro.navigateBack() Taro.showToast({title: '删除成功'})
Taro.navigateBack()
} catch (e) {}
} }
} }
}) })
@ -98,6 +101,14 @@ const UserInfo: FC = () => {
}) })
}, []) }, [])
Taro.useDidShow(() => {
if (data) {
userApi.info(router.params.userId!).then(res => {
setData(res)
})
}
})
return ( return (
<View className={styles.page}> <View className={styles.page}>
<Info data={data}/> <Info data={data}/>
@ -106,7 +117,7 @@ const UserInfo: FC = () => {
<Tabs tabList={tabList} onChange={tabChange}/> <Tabs tabList={tabList} onChange={tabChange}/>
<View className='font-weight font-36 mt-5 mb-3'> <View className='font-weight font-36 mt-5 mb-3'>
<Text style={{margin: '0 10px', color: '#00D6AC'}}>{lineData.reduce((pre, cur) => pre + cur.value, 0)}</Text> <Text style={{margin: '0 10px', color: '#00D6AC'}}>{lineData.reduce((pre, cur) => pre + cur.value, 0)}</Text>
</View> </View>
<LineChart data={lineData}/> <LineChart data={lineData}/>

29
types/user.d.ts vendored

@ -78,19 +78,20 @@ interface CueStats {
/** 课时学习记录 */ /** 课时学习记录 */
interface HourHistory { interface HourHistory extends Curriculum {
id: number; userCourseRecord: {
duration: number; id: number;
course: Curriculum; duration: number;
user_id: number; user_id: number;
created_date: string; created_date: string;
start_at: string; start_at: string;
end_at: string; end_at: string;
course_id: number; course_id: number;
hour_id: number; hour_id: number;
unique_ident: number; unique_ident: number;
total_hour_count: number; hour_count: number;
finished_count: number; finished_count: number;
}
} }
@ -98,5 +99,5 @@ interface Offline {
depid: number depid: number
start_time: number start_time: number
end_time: number end_time: number
path:string path: string
} }

Loading…
Cancel
Save