diff --git a/src/api/course.ts b/src/api/course.ts index 0927db7..913b081 100644 --- a/src/api/course.ts +++ b/src/api/course.ts @@ -20,6 +20,10 @@ export const courseApi = { }, /** 获取部门课程 */ getCourseAll(data: CourseAllParam) { - return request('/api/v1/course/all/company', "GET", data) + return request<{ data: Curriculum[], total: number }>('/api/v1/course/all/company', "GET", data) + }, + /** 删除公司课程 */ + delCourse(course_id: number) { + return request(`/api/v1/course/del/${course_id}`, "DELETE") } } diff --git a/src/api/manage.ts b/src/api/manage.ts index e5d4538..ba13c5d 100644 --- a/src/api/manage.ts +++ b/src/api/manage.ts @@ -46,22 +46,9 @@ export interface depCurProps { interface AddCurProps { course_id: number[] dep_id: number[] - is_required: 1 | 0 + is_required: (1 | 0)[] } -export interface CurLearningRecord { - course: Curriculum - data: User[] - /** 部门 */ - departments: Record - /** 第一次记录 */ - user_course_hour_user_first_at: Record - /** 学习记录 */ - user_course_records: Record - /** 学员部门 */ - user_dep_ids: Record - total: number -} interface DepListData { data: User[] diff --git a/src/components/dateTimePicker/dateTimePicker.tsx b/src/components/dateTimePicker/dateTimePicker.tsx index 67c3d4a..60a26f8 100644 --- a/src/components/dateTimePicker/dateTimePicker.tsx +++ b/src/components/dateTimePicker/dateTimePicker.tsx @@ -1,33 +1,33 @@ import {FC} from "react"; -import {Picker, View} from "@tarojs/components"; interface Props { children: JSX.Element disabled?: boolean } -const DateTimePicker: FC = (props) => { +const DateTimePicker: FC = () => { - function bindMultiPickerChange(e) { - let activityArray = JSON.parse(JSON.stringify(this.activityArray)), - {value} = e.detail, - _result = []; - for (let i = 0; i < value.length; i++) { - _result[i] = activityArray[i][value[i]].id; - } - this.$emit("result", _result); - } + // function bindMultiPickerChange() { + // let activityArray = JSON.parse(JSON.stringify(this.activityArray)), + // {value} = e.detail, + // _result = []; + // for (let i = 0; i < value.length; i++) { + // _result[i] = activityArray[i][value[i]].id; + // } + // this.$emit("result", _result); + // } return ( - - {props.children}12 - + <> + // + // {props.children}12 + // ) } diff --git a/src/pages/manage/courseAdmin/components/search.tsx b/src/pages/manage/courseAdmin/components/search.tsx index 0ea9d7d..4f70c80 100644 --- a/src/pages/manage/courseAdmin/components/search.tsx +++ b/src/pages/manage/courseAdmin/components/search.tsx @@ -1,11 +1,12 @@ import {FC, useCallback, useEffect, useState} from "react"; -import {Input, Radio, Text, View} from "@tarojs/components"; +import {Image, Input, Radio, Text, View} from "@tarojs/components"; import styles from "../courseAdmin.module.scss"; import Icon from "@/components/icon"; import {CourseAllParam, curriculum} from "@/api"; import CustomPageContainer from "@/components/custom-page-container/custom-page-container"; import Empty from "@/components/empty/empty"; import MyButton from "@/components/button/MyButton"; +import screen from '@/static/img/screen.png' interface Props { param: CourseAllParam @@ -36,7 +37,11 @@ export const Search: FC = ({param, setParam}) => { const putParam = useCallback(() => { setShow(false) if (param.dep_id !== depId) { - setParam({...param, dep_id: depId}) + setParam({ + ...param, + dep_id: depId, + page: 1 + }) } }, [depId]) @@ -53,10 +58,16 @@ export const Search: FC = ({param, setParam}) => { placeholder='搜索名称' className='ml-1 flex-1' value={param.title} - onBlur={(e) => setParam({...param, title: e.detail.value})}/> + onBlur={(e) => setParam({ + ...param, + title: e.detail.value, + page: 1 + })}/> setShow(true)}> 筛选 + diff --git a/src/pages/manage/courseAdmin/courseAdmin.config.ts b/src/pages/manage/courseAdmin/courseAdmin.config.ts index 01dfde5..84de6da 100644 --- a/src/pages/manage/courseAdmin/courseAdmin.config.ts +++ b/src/pages/manage/courseAdmin/courseAdmin.config.ts @@ -1,3 +1,4 @@ export default definePageConfig({ navigationBarTitleText: '课程管理', + onReachBottomDistance: 30 }) diff --git a/src/pages/manage/courseAdmin/courseAdmin.module.scss b/src/pages/manage/courseAdmin/courseAdmin.module.scss index 6f3b856..d13faf8 100644 --- a/src/pages/manage/courseAdmin/courseAdmin.module.scss +++ b/src/pages/manage/courseAdmin/courseAdmin.module.scss @@ -7,7 +7,7 @@ } .searchInput { - width: 570rpx; + width: 550rpx; height: 68rpx; display: flex; align-items: center; @@ -28,3 +28,49 @@ overflow: auto; padding: 20px 0; } + +.curBox { + background: #fff; + margin-top: 20px; +} + +.curTitle { + padding: 30rpx; + display: flex; + border-bottom: 1px solid #F5F8F7; +} + +.curImage { + width: 280rpx; + height: 164rpx; + border-radius: 10rpx; + margin: 0 20px; + background: #eee; +} + +.Operation { + display: flex; + justify-content: space-around; + padding: 30rpx 0; +} + +.curList { + padding-bottom: 100px; +} + +.add { + border-top: 1px solid #F5F8F7; + background: #FFFFFF; + text-align: center; + position: fixed; + bottom: 0; + padding-bottom: env(safe-area-inset-bottom); + width: 100%; + color: #45D4A8; +} + +.addBatch { + display: flex; + justify-content: space-between; + padding: 30rpx; +} diff --git a/src/pages/manage/courseAdmin/courseAdmin.tsx b/src/pages/manage/courseAdmin/courseAdmin.tsx index 02530dc..7d1f4bf 100644 --- a/src/pages/manage/courseAdmin/courseAdmin.tsx +++ b/src/pages/manage/courseAdmin/courseAdmin.tsx @@ -1,9 +1,17 @@ -import {FC, useEffect, useState} from "react"; -import {View} from "@tarojs/components"; +import {FC, useCallback, useEffect, useState} from "react"; +import {Image, Radio, Text, View} from "@tarojs/components"; import {Search} from "./components/search"; -import {CourseAllParam, courseApi} from "@/api"; +import {CourseAllParam, courseApi, ManageApi} from "@/api"; +import styles from './courseAdmin.module.scss' +import Taro, {useReachBottom} from "@tarojs/taro"; +import MyButton from "@/components/button/MyButton"; +import storageDep from "@/hooks/storageDep"; const CourseAdmin: FC = () => { + const [total, setTotal] = useState(0) + const [data, setData] = useState([]) + const [batch, setBatch] = useState(false) + const [curs, setCurs] = useState([]) const [param, setParam] = useState({ page: 1, page_size: 10, @@ -11,13 +19,170 @@ const CourseAdmin: FC = () => { dep_id: 0 }) + /** + *@param replace 替换 + */ + function getData(replace = false) { + courseApi.getCourseAll({...param, page_size: param.page_size * (replace ? param.page : 1)}).then(res => { + setTotal(res.total) + if (param.page === 1 || replace) { + setData(res.data) + } else { + setData([ + ...data, + ...res.data, + ]) + } + }) + } + useEffect(() => { - courseApi.getCourseAll(param) + getData() }, [param]) + useReachBottom(() => { + if (data.length < total) { + setParam({ + ...param, + page: param.page + 1 + }) + } + }) + + function all() { + if (curs.length === data.length) { + setCurs([]) + } else { + setCurs(data.map(d => d.id)) + } + } + + function addCurs(id: number) { + const index = curs.indexOf(id) + if (index === -1) { + setCurs([...curs, id]) + } else { + const old: number[] = JSON.parse(JSON.stringify(curs)) + old.splice(index, 1) + setCurs(old) + } + } + + function del(id: number, index: number) { + Taro.showModal({ + title: '删除警告', + content: "删除后所有部门不可查看", + async success({confirm}) { + if (confirm) { + try { + await courseApi.delCourse(id) + Taro.showToast({title: '删除成功'}) + const oldData: Curriculum[] = JSON.parse(JSON.stringify(data)) + oldData.splice(index, 1) + setData(oldData) + } catch (e) { + } + } + } + }) + } + + function changeDep(id: number, data: CurDepInfo[]) { + const depList: Number[] = [] + const required: Number[] = [] + + data.forEach(d => { + depList.push(d.dep_id) + required.push(d.is_required) + }) + + // @ts-ignore + batchChangDep([id], depList, required) + } + + /** + * 批量添加部门 + * @param ids 课程id + * @param depList 批量添加为空[] + * @param required 批量添加为[] + */ + function batchChangDep(ids: number[], depList = [], required = []) { + if (!ids.length) { + Taro.showToast({title: '请选择课程', icon: 'none'}) + return + } + + if (ids.length === 1) { + setCurs(ids) + } + Taro.navigateTo({url: `/pages/manage/selectDep/selectDep?depIds=${JSON.stringify(depList)}&required=${JSON.stringify(required)}`}) + } + + Taro.useDidShow(useCallback(async () => { + const dep_id = storageDep.get() + const is_required = storageDep.getRequired() + + if (!dep_id.length || !is_required.length || !curs.length) return; + + + try { + await ManageApi.addCur({course_id: curs, dep_id, is_required}) + Taro.showToast({title: '修改成功'}) + // deps 中没有 筛选条件中的depid 删除已选的课程 + if (param.dep_id && dep_id.includes(param.dep_id)) { + const newData = data.reduce((pre, cur) => { + if (!dep_id.includes(cur.id)) { + pre.push(cur) + } + return pre + }, [] as Curriculum[]) + setData(newData) + } else { + getData() + } + } catch (e) { + + } + }, [curs, data])) + + return ( + + + { + data.map((d, index) => + addCurs(d.id)}> + {batch && addCurs(d.id)}/>} + + {d.title} + + + del(d.id, index)}>删除 + changeDep(d.id, d.data)}>添加部门 + + ) + } + + + + { + !batch + && data.length > 0 + && setBatch(true)}>添加部门 + } + { + batch && + 全选 + setBatch(false)}>取消 + batchChangDep(curs)}>确定{curs.length} + + } + ) } diff --git a/src/pages/manage/depAdmin/depAdmin.tsx b/src/pages/manage/depAdmin/depAdmin.tsx index 3e49426..5287b66 100644 --- a/src/pages/manage/depAdmin/depAdmin.tsx +++ b/src/pages/manage/depAdmin/depAdmin.tsx @@ -11,7 +11,6 @@ import {Profile} from '@/store' const DepAdmin: FC = () => { const router = useRouter() - // const params = getCurrentInstance()?.router?.params as { dep_id: string, name: string, id: string } const [manages, setManages] = useState([]) const [show, setShow] = useState(false) const [users, setUsers] = useState([]) @@ -94,6 +93,10 @@ const DepAdmin: FC = () => { } const addDep = useCallback(async () => { + if (!depName) { + Taro.showToast({title: '请填写部门名称!', icon: 'error'}) + return + } try { if (isPut) { await ManageApi.putDep(router.params.id!, depName) @@ -163,7 +166,7 @@ const DepAdmin: FC = () => { setShow(false)} onOk={addDep} > diff --git a/src/pages/manage/selectDep/selectDep.tsx b/src/pages/manage/selectDep/selectDep.tsx index f5bbf4f..4838a77 100644 --- a/src/pages/manage/selectDep/selectDep.tsx +++ b/src/pages/manage/selectDep/selectDep.tsx @@ -1,5 +1,5 @@ import React, {FC, useCallback, useEffect, useState} from "react"; -import {Checkbox, View} from "@tarojs/components"; +import {Checkbox, Switch, View} from "@tarojs/components"; import Taro from "@tarojs/taro"; import {curriculum} from "@/api"; import PopPut from "@/components/popPut/popPut"; @@ -51,7 +51,7 @@ const SelectDep: FC = () => { function ok() { if (!ids.length) { - Taro.showToast({title: '请选着部门', icon: "error"}) + Taro.showToast({title: '请选择部门', icon: "error"}) return } storageDep.set(ids) @@ -59,16 +59,50 @@ const SelectDep: FC = () => { Taro.navigateBack({delta: 1}) } + + function isRequired(dep_id: number): boolean { + const index = ids.indexOf(dep_id) + if (index === -1) { + return false + } else { + return !!required?.[index] + } + } + + function requiredChange(dep_id: number, value: boolean) { + const index = ids.indexOf(dep_id) + if (index === -1) { + setIds([...ids, dep_id]) + setRequired([...required, value ? 1 : 0]) + } else { + const oldRequired: number[] = JSON.parse(JSON.stringify(required)) + oldRequired.splice(index, 1, value ? 1 : 0) + setRequired(oldRequired) + } + } + return ( {deps.map((d) => onChange(d.id)}> - + + + 必修: event?.stopImmediatePropagation()} + checked={isRequired(d.id)} + onChange={(e) => requiredChange(d.id, e.detail.value)}/> + + : null + } + /> + )} diff --git a/src/static/img/screen.png b/src/static/img/screen.png new file mode 100644 index 0000000..8fb4861 Binary files /dev/null and b/src/static/img/screen.png differ diff --git a/types/curriculum.d.ts b/types/curriculum.d.ts index 191eff1..bb7f0b1 100644 --- a/types/curriculum.d.ts +++ b/types/curriculum.d.ts @@ -1,3 +1,9 @@ +/** 课程划分部门 和 必修 */ +interface CurDepInfo { + dep_id: number + is_required: 0 | 1 +} + interface Curriculum { id: number; title: string; @@ -13,8 +19,9 @@ interface Curriculum { thumb: string; /** 时间 */ course_duration: number + data: CurDepInfo[] - [key:string]:any + [key: string]: any } /** 课程信息 */ @@ -91,7 +98,7 @@ interface LearnRecord { /** 学习记录 */ interface HourCacheParam { - courseId:number + courseId: number /** 视频学习时长 */ duration: number; /** 课时结束学习时间 */ @@ -100,5 +107,5 @@ interface HourCacheParam { /** 课时开始学习时间 */ start_date: number; user_id: number; - unique_ident:number + unique_ident: number }