feat: 课程模块更名为 clazz(路由 /clazz、store、通知与选型)
对接 AuthCoreJS 通知枚举与 clazz_id;打卡与通知页使用 clazz 字段;补充 package-lock。 Made-with: Cursor
This commit is contained in:
Generated
+16529
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -12,7 +12,7 @@
|
||||
"typecheck": "vuedx-typecheck ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@authcore/commons": "github:alchemy-studio/AuthCoreJS",
|
||||
"@authcore/commons": "file:../AuthCoreJS",
|
||||
"@fullcalendar/bootstrap5": "^6.1.10",
|
||||
"@fullcalendar/core": "^6.1.10",
|
||||
"@fullcalendar/daygrid": "^6.1.10",
|
||||
|
||||
+2
-2
@@ -3,12 +3,12 @@
|
||||
<van-tabbar route v-if="!hide_bottom_tab && user.enabled && user.is_registered && current_role && user.real_name" :before-change="tab_change_check">
|
||||
<van-tabbar-item name="首页" replace to="/" icon="home-o">首页</van-tabbar-item>
|
||||
<template v-if="is_student">
|
||||
<van-tabbar-item name="课程" replace to="/kecheng" icon="calendar-o">课程</van-tabbar-item>
|
||||
<van-tabbar-item name="课程" replace to="/clazz" icon="calendar-o">课程</van-tabbar-item>
|
||||
<van-tabbar-item name="打卡" replace to="/daka" icon="completed-o">打卡</van-tabbar-item>
|
||||
</template>
|
||||
<template v-if="is_teacher">
|
||||
<van-tabbar-item name="教学资源库" replace to="/course/summary" icon="music-o">教学资源库</van-tabbar-item>
|
||||
<van-tabbar-item name="课程" replace to="/kecheng" icon="calendar-o">课程</van-tabbar-item>
|
||||
<van-tabbar-item name="课程" replace to="/clazz" icon="calendar-o">课程</van-tabbar-item>
|
||||
<van-tabbar-item name="打卡" replace to="/daka" icon="completed-o">打卡</van-tabbar-item>
|
||||
</template>
|
||||
<template v-if="is_admin">
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
</div>
|
||||
<van-form @submit="save">
|
||||
<div class="form-content">
|
||||
<van-field label="课程名称" required v-model="store.current.kecheng_name" :readonly="state.readonly"/>
|
||||
<van-field v-model="store.current.kecheng_desc" label="课程描述" autosize rows="2" type="textarea" :readonly="state.readonly"/>
|
||||
<van-field label="课程名称" required v-model="store.current.clazz_name" :readonly="state.readonly"/>
|
||||
<van-field v-model="store.current.clazz_desc" label="课程描述" autosize rows="2" type="textarea" :readonly="state.readonly"/>
|
||||
<template v-if="state.readonly">
|
||||
<van-field :model-value="dateTimeFormat(store.current.start_from)" readonly label="上课时间" required />
|
||||
<van-field label="下课时间" readonly required :model-value="dateTimeFormat(store.current.end_by)" />
|
||||
@@ -101,6 +101,7 @@
|
||||
</div>
|
||||
<div class="footer" v-if="is_creator || !store.current.id ">
|
||||
<template v-if="state.readonly">
|
||||
<van-cell v-if="is_creator && store.current.id && !store.current.is_repeat" title="点名(消课)" is-link @click="openAttendance"/>
|
||||
<van-button size="mini" type="primary" @click="edit(true)" v-if="is_creator && (store.current.instance || store.current.has_root)">编辑重复课程</van-button>
|
||||
<van-button size="mini" type="primary" @click="edit(false)">编辑本次课程</van-button>
|
||||
<van-button size="mini" type="danger" @click="remove(true)" v-if="is_creator && (store.current.instance || store.current.has_root)">取消重复课程</van-button>
|
||||
@@ -119,6 +120,17 @@
|
||||
:columns-type="['hour', 'minute']" :filter="timePickerFilter" />
|
||||
</van-action-sheet>
|
||||
|
||||
<van-popup v-model:show="state.showAttendance" position="bottom" round :style="{ padding: '1rem' }">
|
||||
<h3 style="margin: 0 0 0.75rem;">点名 — 勾选已到学员</h3>
|
||||
<div v-for="u in attendanceStudents" :key="u.user_id || ''" style="margin: 0.5rem 0;">
|
||||
<van-checkbox v-model="attendanceMap[u.user_id || '']" shape="square">{{ u.real_name || u.user_id }}</van-checkbox>
|
||||
</div>
|
||||
<div style="margin-top: 1rem; display: flex; gap: 0.5rem; justify-content: flex-end;">
|
||||
<van-button size="small" @click="state.showAttendance = false">取消</van-button>
|
||||
<van-button size="small" type="primary" @click="submitAttendance">保存</van-button>
|
||||
</div>
|
||||
</van-popup>
|
||||
|
||||
<van-action-sheet :lock-scroll="false" v-model:show="replying" title="留言回复" @close="removeComment" :close-on-click-overlay="false">
|
||||
<comments-sheet :disabled="!is_teacher" :ref_id="store.current.id" :comment="commenting" @reply="replyComment" @submit="saveComment" @remove="removeComment"></comments-sheet>
|
||||
</van-action-sheet>
|
||||
@@ -135,9 +147,9 @@ import zhLocale from '@fullcalendar/core/locales/zh-cn'
|
||||
import bootstrap5Plugin from '@fullcalendar/bootstrap5'
|
||||
import CourseGroup from "~/components/qumu-section-group.vue";
|
||||
import CommentsSheet from '~/components/comments-sheet.vue'
|
||||
import {Field, Cell, Checkbox, Calendar, showConfirmDialog, TimePicker, Button, Tag, Badge, ActionSheet, Overlay, Form, Icon, showFailToast} from 'vant'
|
||||
import {Field, Cell, Checkbox, Calendar, showConfirmDialog, TimePicker, Button, Tag, Badge, ActionSheet, Overlay, Form, Icon, showFailToast, Popup, showSuccessToast} from 'vant'
|
||||
import {DateFormatter, formatDate, hexToRgb} from "~/utils";
|
||||
import useKecheng from "../../store/kecheng";
|
||||
import useClazz from "../../store/clazz";
|
||||
import {useRouter} from "vue-router";
|
||||
import {
|
||||
Comment,
|
||||
@@ -146,7 +158,7 @@ import {
|
||||
GroupUser,
|
||||
HtyBaseRoles,
|
||||
HtySuperRoles,
|
||||
Kecheng,
|
||||
Clazz,
|
||||
NotifyParam,
|
||||
NotifyTypes,
|
||||
PickTargets,
|
||||
@@ -158,7 +170,7 @@ import useComment from "~/store/comment";
|
||||
import useSupervisor from "~/store/supervisor";
|
||||
|
||||
export default defineComponent({
|
||||
name: "kecheng",
|
||||
name: "clazz",
|
||||
components: {
|
||||
FullCalendar,
|
||||
[Icon.name]: Icon,
|
||||
@@ -174,14 +186,15 @@ export default defineComponent({
|
||||
[Button.name]: Button,
|
||||
[Overlay.name]: Overlay,
|
||||
[Form.name]: Form,
|
||||
[CourseGroup.name]: CourseGroup
|
||||
[CourseGroup.name]: CourseGroup,
|
||||
[Popup.name]: Popup,
|
||||
},
|
||||
props: {
|
||||
params: {}
|
||||
},
|
||||
setup({params}: any) {
|
||||
const router = useRouter();
|
||||
const {store, query_repeats, query, query_for_subsidiaries, query_repeats_for_subsidiaries, createOrUpdate, createInstance, removeCurrent, notify} = useKecheng();
|
||||
const {store, query_repeats, query, query_for_subsidiaries, query_repeats_for_subsidiaries, createOrUpdate, createInstance, removeCurrent, notify, find_clazz_attendance_by_clazz_id, batch_save_clazz_attendance} = useClazz();
|
||||
const {set: setPool, setKey, getKey} = usePool();
|
||||
const usingSupervisor = useSupervisor();
|
||||
const usingUser = useUser();
|
||||
@@ -196,9 +209,14 @@ export default defineComponent({
|
||||
readonly: false,
|
||||
showCalendar: false,
|
||||
showTimePicker: false,
|
||||
show_courses: false
|
||||
show_courses: false,
|
||||
showAttendance: false,
|
||||
})
|
||||
|
||||
const attendanceMap = reactive<Record<string, boolean>>({})
|
||||
|
||||
const attendanceStudents = computed(() => store.current.students?.val?.users?.vals || [])
|
||||
|
||||
const calendar = ref(null)
|
||||
const footer = ref(null)
|
||||
|
||||
@@ -218,7 +236,7 @@ export default defineComponent({
|
||||
if (item.is_delete) return;
|
||||
api.addEvent({
|
||||
id: item.id,
|
||||
title: item.kecheng_name,
|
||||
title: item.clazz_name,
|
||||
start: item.start_from,
|
||||
end: item.end_by,
|
||||
})
|
||||
@@ -228,7 +246,7 @@ export default defineComponent({
|
||||
if (!item.instance.id) {
|
||||
api.addEvent({
|
||||
id: item.id,
|
||||
title: item.instance.kecheng_name,
|
||||
title: item.instance.clazz_name,
|
||||
start: item.instance.start_from,
|
||||
end: item.instance.end_by,
|
||||
color: "rgba(55, 136, 216, 0.6)",
|
||||
@@ -237,7 +255,7 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
|
||||
Object.entries(store.subsidiaryKCs).forEach(([key, {list, repeatList}]) => {
|
||||
Object.entries(store.subsidiaryClazzByHtyId).forEach(([key, {list, repeatList}]) => {
|
||||
let color = Colors[subsidiaries.value.findIndex(x => x.to_user_id === key)];
|
||||
let {r, g, b} = hexToRgb(color);
|
||||
let hidden = !viewingSubsidiaries.value.includes(key)
|
||||
@@ -245,7 +263,7 @@ export default defineComponent({
|
||||
if (item.is_delete) return;
|
||||
api.addEvent({
|
||||
id: item.id,
|
||||
title: item.kecheng_name,
|
||||
title: item.clazz_name,
|
||||
start: item.start_from,
|
||||
end: item.end_by,
|
||||
subsidiary_id: key,
|
||||
@@ -257,7 +275,7 @@ export default defineComponent({
|
||||
if (!item.instance.id) {
|
||||
api.addEvent({
|
||||
id: item.id,
|
||||
title: item.instance.kecheng_name,
|
||||
title: item.instance.clazz_name,
|
||||
start: item.instance.start_from,
|
||||
end: item.instance.end_by,
|
||||
color: `rgba(${r}, ${g}, ${b}, 0.6)`,
|
||||
@@ -295,12 +313,12 @@ export default defineComponent({
|
||||
const viewingSubsidiaries = ref([])
|
||||
|
||||
const notify_comment = (comment: Comment) => {
|
||||
let {kecheng_name, start_from, end_by} = store.current;
|
||||
let comment_msg = "新的课程留言(" + kecheng_name + " " + usingUser.store.current.real_name + ")"
|
||||
let {clazz_name, start_from, end_by} = store.current;
|
||||
let comment_msg = "新的课程留言(" + clazz_name + " " + usingUser.store.current.real_name + ")"
|
||||
let payload: NotifyParam = {
|
||||
kecheng_name, start_from, end_by,
|
||||
notify_type: NotifyTypes.TeacherCommentKecheng,
|
||||
kecheng_id: store.current.id, comment_id: comment.id,
|
||||
clazz_name: clazz_name, start_from, end_by,
|
||||
notify_type: NotifyTypes.TeacherCommentClazz,
|
||||
clazz_id: store.current.id, comment_id: comment.id,
|
||||
comment_time: formatDate(new Date(), DateFormatter.DateTime),
|
||||
comment_msg, teacher_name: usingUser.store.current.real_name
|
||||
}
|
||||
@@ -316,7 +334,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
const replyComment = (parent_id?: string) => {
|
||||
commenting.value = { parent_id, ref_type: CommentRefTypes.Kecheng, content: {} as CommentContent} as Comment
|
||||
commenting.value = { parent_id, ref_type: CommentRefTypes.Clazz, content: {} as CommentContent} as Comment
|
||||
}
|
||||
|
||||
const saveComment = async () => {
|
||||
@@ -337,7 +355,7 @@ export default defineComponent({
|
||||
const comments_count = computed(() => count_comments(store.current.id))
|
||||
|
||||
const searchForSubsidiaries = async () => {
|
||||
// query kechengs of subsidiary teachers under current user if user is supervisor
|
||||
// query clazz rows of subsidiary teachers under current user if user is supervisor
|
||||
if (usingUser.store.currentRole === HtyBaseRoles.TEACHER && usingUser.store.current.roles.some(r => r.role_key === HtySuperRoles.SUPERVISOR)) {
|
||||
subsidiaries.value = usingSupervisor.store.subsidiaries;
|
||||
if (!subsidiaries.value.length) {
|
||||
@@ -378,7 +396,7 @@ export default defineComponent({
|
||||
return root.instance;
|
||||
}
|
||||
// find in subsidiaries' list
|
||||
let subsidiaries = Object.values(store.subsidiaryKCs);
|
||||
let subsidiaries = Object.values(store.subsidiaryClazzByHtyId);
|
||||
for (let i = 0; i < subsidiaries.length; i++) {
|
||||
let {list, repeatList} = subsidiaries[i]
|
||||
data = list.find(x => x.id === id)
|
||||
@@ -412,7 +430,7 @@ export default defineComponent({
|
||||
initialDate = new Date(params.start_from)
|
||||
}
|
||||
if (store.hanging) {
|
||||
let { date } = getKey('kecheng_state')
|
||||
let { date } = getKey('clazz_state')
|
||||
initialDate = date;
|
||||
}
|
||||
|
||||
@@ -472,7 +490,7 @@ export default defineComponent({
|
||||
datesSet: function({start, end}) {
|
||||
if (store.hanging) {
|
||||
store.hanging = false;
|
||||
let {state: cachedState} = getKey('kecheng_state');
|
||||
let {state: cachedState} = getKey('clazz_state');
|
||||
Object.entries(cachedState || {}).forEach(([k, v]) => {
|
||||
state[k] = v;
|
||||
})
|
||||
@@ -484,7 +502,7 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
eventDidMount({event}) {
|
||||
if (!store.hanging && state.initial && event.id === params.kecheng_id) {
|
||||
if (!store.hanging && state.initial && event.id === params.clazz_id) {
|
||||
view(event.id)
|
||||
if (params.comment_id) {
|
||||
replying.value = true;
|
||||
@@ -515,7 +533,7 @@ export default defineComponent({
|
||||
if (store.current.instance) {
|
||||
if (await createInstance(store.current.instance)) {
|
||||
state.editing = false;
|
||||
store.current = {} as Kecheng;
|
||||
store.current = {} as Clazz;
|
||||
await search()
|
||||
return;
|
||||
}
|
||||
@@ -523,7 +541,7 @@ export default defineComponent({
|
||||
}
|
||||
if (await createOrUpdate()) {
|
||||
state.editing = false;
|
||||
store.current = {} as Kecheng;
|
||||
store.current = {} as Clazz;
|
||||
await search()
|
||||
}
|
||||
}
|
||||
@@ -531,23 +549,23 @@ export default defineComponent({
|
||||
const freeze = () => {
|
||||
store.hanging = true;
|
||||
let date = calendar.value.getApi().getDate();
|
||||
setKey('kecheng_state', {state, date})
|
||||
setKey('clazz_state', {state, date})
|
||||
}
|
||||
|
||||
const pickUserGroup = () => {
|
||||
freeze();
|
||||
router.push('/user-group/pick?target=' + PickTargets.KECHENG)
|
||||
router.push('/user-group/pick?target=' + PickTargets.CLAZZ)
|
||||
}
|
||||
|
||||
const pickStudent = () => {
|
||||
store.hanging = true;
|
||||
freeze();
|
||||
router.push('/student?multiple=1&target=' + PickTargets.KECHENG)
|
||||
router.push('/student?multiple=1&target=' + PickTargets.CLAZZ)
|
||||
}
|
||||
|
||||
const pickTeacher = () => {
|
||||
freeze();
|
||||
router.push("/teacher/subsidiaries?multiple=1&target=" + PickTargets.KECHENG)
|
||||
router.push("/teacher/subsidiaries?multiple=1&target=" + PickTargets.CLAZZ)
|
||||
}
|
||||
|
||||
const createDaka = async () => {
|
||||
@@ -557,15 +575,15 @@ export default defineComponent({
|
||||
teachers: store.current.teachers,
|
||||
students: store.current.students,
|
||||
})
|
||||
// create kecheng if it's root
|
||||
// create clazz-linked daka if it's root
|
||||
if (!store.current.id) {
|
||||
if (await createInstance(store.current)) {
|
||||
await router.push('/daka/add?kecheng_id=' + store.current.id + '&kecheng_name=' + store.current.kecheng_name)
|
||||
await router.push('/daka/add?clazz_id=' + store.current.id + '&clazz_name=' + encodeURIComponent(store.current.clazz_name))
|
||||
} else {
|
||||
showFailToast("课程创建失败!")
|
||||
}
|
||||
} else {
|
||||
await router.push('/daka/add?kecheng_id=' + store.current.id + '&kecheng_name=' + store.current.kecheng_name)
|
||||
await router.push('/daka/add?clazz_id=' + store.current.id + '&clazz_name=' + encodeURIComponent(store.current.clazz_name))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -578,7 +596,7 @@ export default defineComponent({
|
||||
|
||||
const pickQS = () => {
|
||||
freeze();
|
||||
router.push('/course/mix-pick?target=' + PickTargets.KECHENG)
|
||||
router.push('/course/mix-pick?target=' + PickTargets.CLAZZ)
|
||||
}
|
||||
|
||||
const removeTeacher = (user: GroupUser) => {
|
||||
@@ -680,12 +698,47 @@ export default defineComponent({
|
||||
|
||||
const isTagPlain = (item) => !viewingSubsidiaries.value.includes(item.to_user_id)
|
||||
|
||||
const openAttendance = async () => {
|
||||
if (!store.current.id) {
|
||||
showFailToast('课程 ID 不存在');
|
||||
return;
|
||||
}
|
||||
state.showAttendance = true;
|
||||
const list = await find_clazz_attendance_by_clazz_id(store.current.id);
|
||||
attendanceStudents.value.forEach((u) => {
|
||||
const uid = u.user_id || '';
|
||||
const row = list?.find((a) => a.student_id === uid);
|
||||
attendanceMap[uid] = row ? row.status === 'NORMAL' : false;
|
||||
});
|
||||
};
|
||||
|
||||
const submitAttendance = async () => {
|
||||
if (!store.current.id) return;
|
||||
const hours = (store.current.duration || 60) / 60;
|
||||
const items = attendanceStudents.value.map((u) => {
|
||||
const uid = u.user_id || '';
|
||||
const present = !!attendanceMap[uid];
|
||||
return {
|
||||
student_id: uid,
|
||||
status: present ? 'NORMAL' : 'ABSENT',
|
||||
deducted_hours: present ? hours : 0,
|
||||
sign_method: 'TEACHER_MANUAL',
|
||||
};
|
||||
});
|
||||
const ok = await batch_save_clazz_attendance({ clazz_id: store.current.id, items });
|
||||
if (ok) {
|
||||
showSuccessToast('已保存点名');
|
||||
state.showAttendance = false;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
options, cancel, save, state, store, removeQS, gotoDaka, subsidiaries, toggleTeacherView,
|
||||
pickTeacher, removeTeacher, calendar, edit, remove, dateFormat, pickQS, timePickerFilter,
|
||||
onChangeDate, pickUserGroup, pickStudent, onChangeTime, createDaka, repeatMinDate, isTagPlain,
|
||||
removeStudent, dateTimeFormat, is_teacher, is_creator, repeatDefaultDate, footer, footerHeight,
|
||||
replyComment, removeComment, saveComment, replying, commenting, comments_count, viewingSubsidiaries
|
||||
replyComment, removeComment, saveComment, replying, commenting, comments_count, viewingSubsidiaries,
|
||||
openAttendance, submitAttendance, attendanceMap, attendanceStudents
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -51,7 +51,7 @@ import {Button, Calendar, Cell, Field, Form, Tag} from 'vant';
|
||||
import {DateFormatter, formatDate} from "~/utils";
|
||||
import {useRouter} from 'vue-router';
|
||||
import useDaka from "~/store/daka";
|
||||
import useKecheng from "~/store/kecheng";
|
||||
import useClazz from "~/store/clazz";
|
||||
import useUser from '~/store/user';
|
||||
import useLoading from "~/store/loading";
|
||||
import {GroupUser, HtySuperRoles, PickTargets} from "~/types";
|
||||
@@ -75,7 +75,7 @@ export default defineComponent({
|
||||
const {store:{current}} = useUser()
|
||||
const {loading} = useLoading();
|
||||
const { get: getPool, remove: removePool, set: setPool } = usePool()
|
||||
const {setDakasForKC} = useKecheng()
|
||||
const {setDakasForClazz} = useClazz()
|
||||
|
||||
const genName = () => {
|
||||
let name = "打卡";
|
||||
@@ -102,9 +102,9 @@ export default defineComponent({
|
||||
const onSubmit = async () => {
|
||||
let id = await create();
|
||||
if (id) {
|
||||
if (params.kecheng_id) {
|
||||
if (params.clazz_id) {
|
||||
let { name, start_date, duration_days } = store.current;
|
||||
await setDakasForKC({id, name, start_date, duration_days});
|
||||
await setDakasForClazz({id, name, start_date, duration_days});
|
||||
reset();
|
||||
await router.back();
|
||||
} else {
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
<div class="title" v-if="item.group_name">
|
||||
<span class="label">学生小组:</span> {{ item.group_name }}
|
||||
</div>
|
||||
<div class="title" v-if="item.kecheng">
|
||||
<span class="label">课程名称:</span> {{ item.kecheng.kecheng_name }}
|
||||
<div class="title" v-if="item.clazz">
|
||||
<span class="label">课程名称:</span> {{ item.clazz.clazz_name }}
|
||||
</div>
|
||||
<div class="line">
|
||||
<label>打卡时限:</label><span :class="{expired: expired(item)}">{{ weekShow(item) }}</span><van-tag :show="item.is_yanqi" style="margin-left: 5px" type="warning">已延期</van-tag>
|
||||
|
||||
@@ -73,7 +73,7 @@ import useDaka from "~/store/daka";
|
||||
import useUser from '~/store/user';
|
||||
import {Daka, HtyBaseRoles} from "~/types";
|
||||
import dayjs from "dayjs";
|
||||
import useKecheng from "~/store/kecheng";
|
||||
import useClazz from "~/store/clazz";
|
||||
import {useRouter} from "vue-router";
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ export default defineComponent({
|
||||
|
||||
const usingUser = useUser();
|
||||
const router = useRouter();
|
||||
const usingKecheng = useKecheng()
|
||||
const usingClazz = useClazz()
|
||||
const {store, query, reset} = useDaka();
|
||||
|
||||
const state = reactive({
|
||||
@@ -157,7 +157,7 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
const onClick = (item: Daka) => {
|
||||
usingKecheng.store.current.daka = item;
|
||||
usingClazz.store.current.daka = item;
|
||||
router.back();
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ import {
|
||||
} from 'vant';
|
||||
import useJihua from "~/store/jihua";
|
||||
import useDaka from '~/store/daka';
|
||||
import useKecheng from "~/store/kecheng";
|
||||
import useClazz from "~/store/clazz";
|
||||
import {useRouter} from "vue-router";
|
||||
import {CourseGroup, PickTargets} from '~/types';
|
||||
import {DateFormatter, formatDate} from "~/utils";
|
||||
@@ -96,7 +96,7 @@ export default defineComponent({
|
||||
setup({params}) {
|
||||
const usingJihua = useJihua();
|
||||
const usingDaka = useDaka();
|
||||
const usingKecheng = useKecheng();
|
||||
const usingClazz = useClazz();
|
||||
const {store:{current:{hty_id}}} = useUser()
|
||||
const state = reactive<CourseState>({
|
||||
loading: false,
|
||||
@@ -208,8 +208,8 @@ export default defineComponent({
|
||||
case PickTargets.DAKA:
|
||||
usingDaka.store.current.course_sections = course_sections;
|
||||
break;
|
||||
case PickTargets.KECHENG:
|
||||
usingKecheng.store.current.course_sections = {vals: course_sections};
|
||||
case PickTargets.CLAZZ:
|
||||
usingClazz.store.current.course_sections = {vals: course_sections};
|
||||
break;
|
||||
}
|
||||
router.back();
|
||||
|
||||
@@ -86,7 +86,7 @@ import useJihua from "~/store/jihua";
|
||||
import useDaka from '~/store/daka';
|
||||
import useCourseGroup from "~/store/qumu-section-group";
|
||||
import useComment from "~/store/comment";
|
||||
import useKecheng from "~/store/kecheng";
|
||||
import useClazz from "~/store/clazz";
|
||||
import CommentsSheet from "~/components/comments-sheet.vue";
|
||||
import QupuMap from "~/components/qupu-map.vue";
|
||||
import HtyImage from "~/components/hty-image.vue";
|
||||
@@ -137,7 +137,7 @@ export default defineComponent({
|
||||
const usingJihua = useJihua();
|
||||
const usingDaka = useDaka();
|
||||
const usingCourseGroup = useCourseGroup();
|
||||
const usingKecheng = useKecheng();
|
||||
const usingClazz = useClazz();
|
||||
const state = reactive<CourseState>({
|
||||
loading: false,
|
||||
finished: false,
|
||||
@@ -263,8 +263,8 @@ export default defineComponent({
|
||||
case PickTargets.COURSE_GROUP:
|
||||
usingCourseGroup.store.current.course_sections = state.checked;
|
||||
break;
|
||||
case PickTargets.KECHENG:
|
||||
usingKecheng.store.current.course_sections = {vals: state.checked}
|
||||
case PickTargets.CLAZZ:
|
||||
usingClazz.store.current.course_sections = {vals: state.checked}
|
||||
break;
|
||||
}
|
||||
router.back();
|
||||
|
||||
@@ -39,7 +39,7 @@ import { useRouter } from 'vue-router';
|
||||
import useJihua from "~/store/jihua";
|
||||
import useUser from "~/store/user";
|
||||
import useUserGroup from '~/store/user-group';
|
||||
import useKecheng from "~/store/kecheng";
|
||||
import useClazz from "~/store/clazz";
|
||||
import useDaka from "~/store/daka";
|
||||
import {PickTargets, TeacherStudentStates, User} from '~/types'
|
||||
|
||||
@@ -62,7 +62,7 @@ export default defineComponent({
|
||||
setup({params}) {
|
||||
|
||||
const usingGroup = useUserGroup();
|
||||
const usingKecheng = useKecheng();
|
||||
const usingClazz = useClazz();
|
||||
const usingDaka = useDaka();
|
||||
|
||||
const state = reactive({
|
||||
@@ -123,11 +123,11 @@ export default defineComponent({
|
||||
case PickTargets.USER_GROUP:
|
||||
state.checked = [...(usingGroup.store.current.users.vals || [])]
|
||||
break;
|
||||
case PickTargets.KECHENG:
|
||||
state.checked = [...(usingKecheng.store.current.students?.val?.users?.vals || [])]
|
||||
case PickTargets.CLAZZ:
|
||||
state.checked = [...(usingClazz.store.current.students?.val?.users?.vals || [])]
|
||||
break;
|
||||
case PickTargets.DAKA:
|
||||
state.checked = [...(usingKecheng.store.current.students?.val?.users?.vals || [])]
|
||||
state.checked = [...(usingClazz.store.current.students?.val?.users?.vals || [])]
|
||||
break;
|
||||
}
|
||||
})
|
||||
@@ -152,12 +152,12 @@ export default defineComponent({
|
||||
case PickTargets.USER_GROUP:
|
||||
usingGroup.store.current.users.vals = [...state.checked];
|
||||
break;
|
||||
case PickTargets.KECHENG:
|
||||
ids = new Set((usingKecheng.store.current.students?.val.users.vals || []).map(x => x.user_id));
|
||||
case PickTargets.CLAZZ:
|
||||
ids = new Set((usingClazz.store.current.students?.val.users.vals || []).map(x => x.user_id));
|
||||
if (ids.size > 0) {
|
||||
usingKecheng.store.current.students.val.users.vals.push(...state.checked.filter(x => !ids.has(x.user_id)))
|
||||
usingClazz.store.current.students.val.users.vals.push(...state.checked.filter(x => !ids.has(x.user_id)))
|
||||
} else {
|
||||
usingKecheng.store.current.students = {val: {users: {vals: [...state.checked]}}}
|
||||
usingClazz.store.current.students = {val: {users: {vals: [...state.checked]}}}
|
||||
}
|
||||
break;
|
||||
case PickTargets.DAKA:
|
||||
|
||||
@@ -39,7 +39,7 @@ import useUserGroup from "~/store/user-group";
|
||||
import useCourseSection from "~/store/qumu-section";
|
||||
import useCourseGroup from "~/store/qumu-section-group";
|
||||
import useUser from "~/store/user";
|
||||
import useKecheng from "~/store/kecheng";
|
||||
import useClazz from "~/store/clazz";
|
||||
|
||||
export default defineComponent({
|
||||
name: "teacher-index",
|
||||
@@ -64,7 +64,7 @@ export default defineComponent({
|
||||
const usingUserGroup = useUserGroup();
|
||||
const usingQS = useCourseSection();
|
||||
const usingQSGroup = useCourseGroup()
|
||||
const usingKecheng = useKecheng()
|
||||
const usingClazz = useClazz()
|
||||
const {store:{current:{supervisor}}} = useUser()
|
||||
|
||||
const { store, getSubsidiaries } = useSupervisor();
|
||||
@@ -144,8 +144,8 @@ export default defineComponent({
|
||||
case PickTargets.COURSE_GROUP:
|
||||
state.checked = [...(usingQSGroup.store.current.teachers?.vals || [])].filter(t => dataset.value.some(x => x.teacher_id === t.teacher_id))
|
||||
break;
|
||||
case PickTargets.KECHENG:
|
||||
state.checked = [...(usingKecheng.store.current.teachers?.val?.users?.vals || [])].filter(t => dataset.value.some(x => x.teacher_id === t.user_id))
|
||||
case PickTargets.CLAZZ:
|
||||
state.checked = [...(usingClazz.store.current.teachers?.val?.users?.vals || [])].filter(t => dataset.value.some(x => x.teacher_id === t.user_id))
|
||||
break;
|
||||
}
|
||||
})
|
||||
@@ -178,8 +178,8 @@ export default defineComponent({
|
||||
case PickTargets.COURSE_GROUP:
|
||||
usingQSGroup.store.current.teachers = {vals: teachers}
|
||||
break;
|
||||
case PickTargets.KECHENG:
|
||||
usingKecheng.store.current.teachers = {val: {users: {vals: teachers.map(t => ({user_id: t.teacher_id, real_name: t.teacher_name}))}}}
|
||||
case PickTargets.CLAZZ:
|
||||
usingClazz.store.current.teachers = {val: {users: {vals: teachers.map(t => ({user_id: t.teacher_id, real_name: t.teacher_name}))}}}
|
||||
break;
|
||||
}
|
||||
router.back();
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
<div class="title" v-if="entity.content?.content">
|
||||
{{ entity.content.content }}
|
||||
</div>
|
||||
<div class="title" v-if="entity.push_info?.kecheng_id">
|
||||
<div class="title" v-if="entity.push_info?.clazz_id">
|
||||
{{ getTongzhiTitle(entity.tongzhi_type) }}
|
||||
</div>
|
||||
<div class="van-cell" @click="onClick">
|
||||
<template v-if="entity.push_info?.kecheng_id">
|
||||
<template v-if="entity.push_info?.clazz_id">
|
||||
<div class="line">
|
||||
<span>课程名称</span>
|
||||
<span>{{ entity.push_info.kecheng_name }}</span>
|
||||
<span>{{ entity.push_info.clazz_name }}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
<span>上课时间</span>
|
||||
@@ -116,7 +116,7 @@ onBeforeUnmount(() => {
|
||||
const entity = computed(() => store.current);
|
||||
|
||||
const onClick = () => {
|
||||
let { jihua_id, lianxi_id, daka_id, ref_id, serial, comment_id, kecheng_id } =
|
||||
let { jihua_id, lianxi_id, daka_id, ref_id, serial, comment_id, clazz_id } =
|
||||
getIds(entity.value);
|
||||
|
||||
let comment_param = comment_id ? "&comment_id=" + comment_id : "";
|
||||
@@ -224,29 +224,29 @@ const onClick = () => {
|
||||
case NotifyTypes.TeacherRegisterApproved:
|
||||
router.back();
|
||||
break;
|
||||
case NotifyTypes.KechengCreateOrUpdate:
|
||||
case NotifyTypes.TeacherCommentKecheng:
|
||||
case NotifyTypes.ClazzCreateOrUpdate:
|
||||
case NotifyTypes.TeacherCommentClazz:
|
||||
let {
|
||||
push_info: { start_from, comment_id },
|
||||
} = tongzhi;
|
||||
} = entity.value;
|
||||
let url =
|
||||
"/kecheng?kecheng_id=" + kecheng_id + "&start_from=" + start_from;
|
||||
"/clazz?clazz_id=" + clazz_id + "&start_from=" + start_from;
|
||||
if (comment_id) {
|
||||
url += "&comment_id=" + comment_id;
|
||||
}
|
||||
router.push(url);
|
||||
break;
|
||||
case NotifyTypes.KechengDelete:
|
||||
router.push("/kecheng");
|
||||
case NotifyTypes.ClazzDelete:
|
||||
router.push("/clazz");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const getTongzhiTitle = (tongzhi_type) => {
|
||||
return {
|
||||
[NotifyTypes.KechengCreateOrUpdate]: "上课时间确定通知",
|
||||
[NotifyTypes.KechengDelete]: "课程预约取消通知",
|
||||
[NotifyTypes.TeacherCommentKecheng]: "课程留言通知",
|
||||
[NotifyTypes.ClazzCreateOrUpdate]: "上课时间确定通知",
|
||||
[NotifyTypes.ClazzDelete]: "课程预约取消通知",
|
||||
[NotifyTypes.TeacherCommentClazz]: "课程留言通知",
|
||||
}[tongzhi_type];
|
||||
};
|
||||
|
||||
@@ -264,13 +264,13 @@ const formatDateTime = (dt: Date | string) =>
|
||||
|
||||
const getIds = ({ content, push_info }: Tongzhi) => {
|
||||
let { ref_id, serial, comment_id } = push_info || {};
|
||||
let { jihua_id, lianxi_id, daka_id, kecheng_id } = content;
|
||||
let { jihua_id, lianxi_id, daka_id, clazz_id } = content;
|
||||
if (!(jihua_id || lianxi_id || daka_id)) {
|
||||
if (push_info) {
|
||||
jihua_id = push_info.jihua_id;
|
||||
lianxi_id = push_info.lianxi_id;
|
||||
daka_id = push_info.daka_id;
|
||||
kecheng_id = push_info.kecheng_id;
|
||||
clazz_id = push_info.clazz_id;
|
||||
}
|
||||
}
|
||||
return {
|
||||
@@ -280,14 +280,14 @@ const getIds = ({ content, push_info }: Tongzhi) => {
|
||||
ref_id,
|
||||
serial,
|
||||
comment_id,
|
||||
kecheng_id,
|
||||
clazz_id,
|
||||
};
|
||||
};
|
||||
|
||||
const gotoDetail = () => {
|
||||
let tongzhi = store.current;
|
||||
|
||||
let { jihua_id, lianxi_id, daka_id, ref_id, serial, comment_id, kecheng_id } =
|
||||
let { jihua_id, lianxi_id, daka_id, ref_id, serial, comment_id, clazz_id } =
|
||||
getIds(tongzhi);
|
||||
|
||||
let comment_param = comment_id ? "&comment_id=" + comment_id : "";
|
||||
@@ -395,20 +395,20 @@ const gotoDetail = () => {
|
||||
case NotifyTypes.TeacherRegisterApproved:
|
||||
router.back();
|
||||
break;
|
||||
case NotifyTypes.KechengCreateOrUpdate:
|
||||
case NotifyTypes.TeacherCommentKecheng:
|
||||
case NotifyTypes.ClazzCreateOrUpdate:
|
||||
case NotifyTypes.TeacherCommentClazz:
|
||||
let {
|
||||
push_info: { start_from, comment_id },
|
||||
} = tongzhi;
|
||||
let url =
|
||||
"/kecheng?kecheng_id=" + kecheng_id + "&start_from=" + start_from;
|
||||
"/clazz?clazz_id=" + clazz_id + "&start_from=" + start_from;
|
||||
if (comment_id) {
|
||||
url += "&comment_id=" + comment_id;
|
||||
}
|
||||
router.push(url);
|
||||
break;
|
||||
case NotifyTypes.KechengDelete:
|
||||
router.push("/kecheng");
|
||||
case NotifyTypes.ClazzDelete:
|
||||
router.push("/clazz");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
+18
-18
@@ -16,12 +16,12 @@
|
||||
<van-swipe-cell>
|
||||
<div class="row van-cell" @click="() => onClick(item)" >
|
||||
<div v-if="item.content?.content">{{item.content.content}}</div>
|
||||
<div v-if="item.push_info?.kecheng_id">{{getTongzhiTitle(item.tongzhi_type)}}<small>({{formatDateTime(item.content.created_at)}})</small></div>
|
||||
<div v-if="item.push_info?.clazz_id">{{getTongzhiTitle(item.tongzhi_type)}}<small>({{formatDateTime(item.content.created_at)}})</small></div>
|
||||
<div class="van-hairline--bottom"></div>
|
||||
<template v-if="item.push_info?.kecheng_id">
|
||||
<template v-if="item.push_info?.clazz_id">
|
||||
<div class="line">
|
||||
<span>课程名称</span>
|
||||
<span>{{item.push_info.kecheng_name}}</span>
|
||||
<span>{{item.push_info.clazz_name}}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
<span>上课时间</span>
|
||||
@@ -75,12 +75,12 @@
|
||||
<van-swipe-cell>
|
||||
<div class="row van-cell read" @click="() => onClick(item)" >
|
||||
<div v-if="item.content?.content">{{item.content.content}}</div>
|
||||
<div v-if="item.push_info?.kecheng_id">{{getTongzhiTitle(item.tongzhi_type)}}<small>({{formatDateTime(item.content.created_at)}})</small></div>
|
||||
<div v-if="item.push_info?.clazz_id">{{getTongzhiTitle(item.tongzhi_type)}}<small>({{formatDateTime(item.content.created_at)}})</small></div>
|
||||
<div class="van-hairline--bottom"></div>
|
||||
<template v-if="item.push_info?.kecheng_id">
|
||||
<template v-if="item.push_info?.clazz_id">
|
||||
<div class="line">
|
||||
<span>课程名称</span>
|
||||
<span>{{item.push_info.kecheng_name}}</span>
|
||||
<span>{{item.push_info.clazz_name}}</span>
|
||||
</div>
|
||||
<div class="line">
|
||||
<span>上课时间</span>
|
||||
@@ -213,17 +213,17 @@ export default defineComponent({
|
||||
|
||||
const getIds = ({content, push_info}: Tongzhi) => {
|
||||
let { ref_id, serial, comment_id } = push_info || {};
|
||||
let { jihua_id, lianxi_id, daka_id, kecheng_id } = content;
|
||||
let { jihua_id, lianxi_id, daka_id, clazz_id } = content;
|
||||
if (!(jihua_id || lianxi_id || daka_id)) {
|
||||
if (push_info) {
|
||||
jihua_id = push_info.jihua_id;
|
||||
lianxi_id = push_info.lianxi_id;
|
||||
daka_id = push_info.daka_id;
|
||||
kecheng_id = push_info.kecheng_id;
|
||||
clazz_id = push_info.clazz_id;
|
||||
}
|
||||
}
|
||||
return {
|
||||
jihua_id, lianxi_id, daka_id, ref_id, serial, comment_id, kecheng_id
|
||||
jihua_id, lianxi_id, daka_id, ref_id, serial, comment_id, clazz_id
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ export default defineComponent({
|
||||
await setRead(tongzhi.tongzhi_id);
|
||||
}
|
||||
|
||||
let { jihua_id, lianxi_id, daka_id, ref_id, serial, comment_id, kecheng_id } = getIds(tongzhi);
|
||||
let { jihua_id, lianxi_id, daka_id, ref_id, serial, comment_id, clazz_id } = getIds(tongzhi);
|
||||
|
||||
let comment_param = comment_id ? "&comment_id=" + comment_id : "";
|
||||
let serial_param = serial ? '&serial=' + serial: '';
|
||||
@@ -313,17 +313,17 @@ export default defineComponent({
|
||||
case NotifyTypes.TeacherRegisterApproved:
|
||||
router.back();
|
||||
break;
|
||||
case NotifyTypes.KechengCreateOrUpdate:
|
||||
case NotifyTypes.TeacherCommentKecheng:
|
||||
case NotifyTypes.ClazzCreateOrUpdate:
|
||||
case NotifyTypes.TeacherCommentClazz:
|
||||
let { push_info: {start_from, comment_id} } = tongzhi;
|
||||
let url = "/kecheng?kecheng_id=" + kecheng_id + "&start_from=" + start_from;
|
||||
let url = "/clazz?clazz_id=" + clazz_id + "&start_from=" + start_from;
|
||||
if (comment_id) {
|
||||
url += "&comment_id=" + comment_id
|
||||
}
|
||||
router.push(url)
|
||||
break;
|
||||
case NotifyTypes.KechengDelete:
|
||||
router.push("/kecheng")
|
||||
case NotifyTypes.ClazzDelete:
|
||||
router.push("/clazz")
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -354,9 +354,9 @@ export default defineComponent({
|
||||
|
||||
const getTongzhiTitle = (tongzhi_type) => {
|
||||
return {
|
||||
[NotifyTypes.KechengCreateOrUpdate]: "上课时间确定通知",
|
||||
[NotifyTypes.KechengDelete]: "课程预约取消通知",
|
||||
[NotifyTypes.TeacherCommentKecheng]: "课程留言通知"
|
||||
[NotifyTypes.ClazzCreateOrUpdate]: "上课时间确定通知",
|
||||
[NotifyTypes.ClazzDelete]: "课程预约取消通知",
|
||||
[NotifyTypes.TeacherCommentClazz]: "课程留言通知"
|
||||
}[tongzhi_type]
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ import {useRouter} from "vue-router";
|
||||
import useUserGroup from '~/store/user-group';
|
||||
import useUser from '~/store/user';
|
||||
import useDaka from '~/store/daka';
|
||||
import useKecheng from "~/store/kecheng";
|
||||
import useClazz from "~/store/clazz";
|
||||
import {UserGroup, PickTargets} from '~/types';
|
||||
|
||||
export interface GroupState {
|
||||
@@ -70,7 +70,7 @@ export default defineComponent({
|
||||
setup({params}) {
|
||||
const router = useRouter();
|
||||
const usingDaka = useDaka();
|
||||
const usingKecheng = useKecheng();
|
||||
const usingClazz = useClazz();
|
||||
const {store:{current:{hty_id}}} = useUser();
|
||||
|
||||
const state = reactive<GroupState>({
|
||||
@@ -135,8 +135,8 @@ export default defineComponent({
|
||||
usingDaka.store.current.teachers?.vals.push({teacher_id: created_by, teacher_name: creator_name})
|
||||
}
|
||||
break;
|
||||
case PickTargets.KECHENG:
|
||||
usingKecheng.store.current.students = {val: {users}}
|
||||
case PickTargets.CLAZZ:
|
||||
usingClazz.store.current.students = {val: {users}}
|
||||
}
|
||||
router.go(-1);
|
||||
}
|
||||
|
||||
+2
-2
@@ -67,7 +67,7 @@ import DakaDetail from '~/pages/daka/detail.vue';
|
||||
import DakaPiyue from '~/pages/daka/piyue.vue';
|
||||
import SupervisorProfile from "~/pages/supervisor/profile.vue"
|
||||
import SupervisorSubsidiaries from "~/pages/supervisor/subsidiaries.vue"
|
||||
import Kecheng from "~/pages/kecheng/index.vue"
|
||||
import ClazzPage from "~/pages/clazz/index.vue"
|
||||
import UserSettings from "~/pages/user-settings.vue";
|
||||
|
||||
import {RouteQueryAndHash} from "vue-router";
|
||||
@@ -245,7 +245,7 @@ export default [
|
||||
meta: {title: "打卡批阅"}, props: ({query}: RouteQueryAndHash) => ({params: query})
|
||||
},
|
||||
{
|
||||
path: '/kecheng', component: Kecheng, meta: {title: "课程"},
|
||||
path: '/clazz', component: ClazzPage, meta: {title: "课程"},
|
||||
props: ({query}: RouteQueryAndHash) => ({params: query})
|
||||
},
|
||||
{path: '/user-settings', component: UserSettings, meta: {title: "个性化设置"}},
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import {reactive} from "vue";
|
||||
import {
|
||||
Clazz,
|
||||
ClazzAttendance,
|
||||
ClazzRepeat,
|
||||
ClazzRepeatStatuses,
|
||||
ClazzStatuses,
|
||||
CourseSection,
|
||||
Daka,
|
||||
HtyBaseRoles,
|
||||
HtyRoles,
|
||||
Kecheng,
|
||||
KechengRepeatStatuses,
|
||||
KechengStatuses,
|
||||
MultiVals,
|
||||
NotifyParam,
|
||||
NotifyTypes,
|
||||
CourseSection,
|
||||
RepeatKecheng
|
||||
ClazzRepeatRow,
|
||||
ReqBatchClazzAttendance,
|
||||
} from "~/types";
|
||||
import useUser from "~/store/user";
|
||||
import useLoading from "~/store/loading";
|
||||
@@ -20,26 +23,26 @@ import {showFailToast} from "vant";
|
||||
import useNotify from "~/store/notify";
|
||||
import {DateFormatter, formatDate} from "~/utils";
|
||||
|
||||
interface KechengStore {
|
||||
interface ClazzStore {
|
||||
hanging: boolean,
|
||||
current: Kecheng,
|
||||
list: Kecheng[],
|
||||
subsidiaryKCs: {
|
||||
[key: string]: {list: Kecheng[], repeatList: RepeatKecheng[]}
|
||||
current: Clazz,
|
||||
list: Clazz[],
|
||||
subsidiaryClazzByHtyId: {
|
||||
[key: string]: {list: Clazz[], repeatList: ClazzRepeatRow[]}
|
||||
}
|
||||
repeatList: RepeatKecheng[]
|
||||
repeatList: ClazzRepeatRow[]
|
||||
}
|
||||
|
||||
const store = reactive<KechengStore>({
|
||||
const store = reactive<ClazzStore>({
|
||||
hanging: false,
|
||||
current: {} as Kecheng,
|
||||
current: {} as Clazz,
|
||||
list: [],
|
||||
subsidiaryKCs: {},
|
||||
subsidiaryClazzByHtyId: {},
|
||||
repeatList: [],
|
||||
})
|
||||
|
||||
|
||||
export default function useKecheng() {
|
||||
export default function useClazz() {
|
||||
|
||||
const {load_start, load_done} = useLoading()
|
||||
const usingUser = useUser();
|
||||
@@ -56,7 +59,7 @@ export default function useKecheng() {
|
||||
let {currentRole, current:{hty_id}} = usingUser.store;
|
||||
load_start()
|
||||
const {r, d, e} = await request({
|
||||
url: "/api/v1/kc/find_all_non_repeatable_kechengs_within_date_range_by_hty_id",
|
||||
url: "/api/v1/clazz/find_all_non_repeatable_within_date_range_by_hty_id",
|
||||
method: "GET", data: {start_from, end_by, hty_id}
|
||||
})
|
||||
load_done()
|
||||
@@ -81,11 +84,11 @@ export default function useKecheng() {
|
||||
|
||||
await Promise.all(hty_ids.map(async hty_id => {
|
||||
const {r, d, e} = await request({
|
||||
url: "/api/v1/kc/find_all_non_repeatable_kechengs_within_date_range_by_hty_id",
|
||||
url: "/api/v1/clazz/find_all_non_repeatable_within_date_range_by_hty_id",
|
||||
method: "GET", data: {start_from, end_by, hty_id}
|
||||
})
|
||||
if (r) {
|
||||
store.subsidiaryKCs[hty_id] = {
|
||||
store.subsidiaryClazzByHtyId[hty_id] = {
|
||||
list: d.filter(x => x.teachers?.val?.users?.vals?.some(u => u.user_id === hty_id)),
|
||||
repeatList: []
|
||||
}
|
||||
@@ -98,24 +101,23 @@ export default function useKecheng() {
|
||||
|
||||
function repeat_prepare(start_from: string, end_by: string, repeatList, nonRepeatList) {
|
||||
return repeatList.map(item => {
|
||||
let kecheng: Kecheng = { kecheng_repeat: {} };
|
||||
let row: Clazz = { clazz_repeat: {} as ClazzRepeat };
|
||||
Object.entries(item).forEach(([k, v]) => {
|
||||
if (k.startsWith("kc_")) {
|
||||
kecheng[k.replace("kc_", "")] = v;
|
||||
if (k.startsWith("clz_")) {
|
||||
(row as Record<string, unknown>)[k.replace("clz_", "")] = v;
|
||||
}
|
||||
if (k.startsWith("re_")) {
|
||||
kecheng.kecheng_repeat[k.replace("re_", "")] = v;
|
||||
const cr = row.clazz_repeat ?? (row.clazz_repeat = {} as ClazzRepeat);
|
||||
(cr as Record<string, unknown>)[k.replace("re_", "")] = v;
|
||||
}
|
||||
})
|
||||
if (kecheng.is_delete) return null;
|
||||
kecheng.repeat_start = formatDate(kecheng.kecheng_repeat?.repeat_start, DateFormatter.Date)
|
||||
kecheng.repeat_end = formatDate(kecheng.kecheng_repeat?.repeat_end, DateFormatter.Date)
|
||||
// check instanced kechengs
|
||||
if (row.is_delete) return null;
|
||||
row.repeat_start = formatDate(row.clazz_repeat?.repeat_start, DateFormatter.Date)
|
||||
row.repeat_end = formatDate(row.clazz_repeat?.repeat_end, DateFormatter.Date)
|
||||
let start = new Date(start_from).valueOf(), end = new Date(end_by).valueOf()
|
||||
let instance = nonRepeatList.find(x => x.root_id === kecheng.id);
|
||||
// move start_from and end_by to current week
|
||||
let kc_start_from = new Date(kecheng.start_from);
|
||||
let kc_end_by = new Date(kecheng.end_by);
|
||||
let instance = nonRepeatList.find(x => x.root_id === row.id);
|
||||
let kc_start_from = new Date(row.start_from);
|
||||
let kc_end_by = new Date(row.end_by);
|
||||
if (!instance) {
|
||||
while (kc_end_by.valueOf() < start) {
|
||||
kc_start_from.setDate(kc_start_from.getDate() + 7)
|
||||
@@ -125,15 +127,15 @@ export default function useKecheng() {
|
||||
kc_start_from.setDate(kc_start_from.getDate() - 7)
|
||||
kc_end_by.setDate(kc_end_by.getDate() - 7)
|
||||
}
|
||||
let {kecheng_repeat, id, is_repeat, ...rest} = kecheng
|
||||
let {clazz_repeat, id, is_repeat, ...rest} = row
|
||||
instance = {
|
||||
...rest,
|
||||
start_from: formatDate(kc_start_from, DateFormatter.DateTimeSave),
|
||||
end_by: formatDate(kc_end_by, DateFormatter.DateTimeSave),
|
||||
}
|
||||
}
|
||||
instance.has_root = true;
|
||||
return {...kecheng, instance};
|
||||
instance!.has_root = true;
|
||||
return {...row, instance};
|
||||
}).filter(x => !!x);
|
||||
}
|
||||
|
||||
@@ -141,7 +143,7 @@ export default function useKecheng() {
|
||||
let {current:{hty_id}} = usingUser.store;
|
||||
load_start()
|
||||
const {r, d, e} = await request({
|
||||
url: "/api/v1/kc/find_all_repeatable_kechengs_within_date_range_by_hty_id",
|
||||
url: "/api/v1/clazz/find_all_repeatable_within_date_range_by_hty_id",
|
||||
method: "GET", data: {start_from, end_by, hty_id}
|
||||
})
|
||||
load_done()
|
||||
@@ -158,12 +160,12 @@ export default function useKecheng() {
|
||||
load_start()
|
||||
await Promise.all(hty_ids.map(async hty_id => {
|
||||
const {r, d, e} = await request({
|
||||
url: "/api/v1/kc/find_all_repeatable_kechengs_within_date_range_by_hty_id",
|
||||
url: "/api/v1/clazz/find_all_repeatable_within_date_range_by_hty_id",
|
||||
method: "GET", data: {start_from, end_by, hty_id}
|
||||
})
|
||||
if (r) {
|
||||
store.subsidiaryKCs[hty_id] = store.subsidiaryKCs[hty_id] || {list: [], repeatList: []}
|
||||
store.subsidiaryKCs[hty_id].repeatList = repeat_prepare(start_from, end_by, d, store.subsidiaryKCs[hty_id].list);
|
||||
store.subsidiaryClazzByHtyId[hty_id] = store.subsidiaryClazzByHtyId[hty_id] || {list: [], repeatList: []}
|
||||
store.subsidiaryClazzByHtyId[hty_id].repeatList = repeat_prepare(start_from, end_by, d, store.subsidiaryClazzByHtyId[hty_id].list);
|
||||
} else {
|
||||
console.error("query failed...", e)
|
||||
}
|
||||
@@ -183,8 +185,8 @@ export default function useKecheng() {
|
||||
}
|
||||
|
||||
async function createOrUpdate() {
|
||||
let { kecheng_name, students, course_sections, kecheng_repeat, start_from, end_by, is_repeat, instance, has_root, repeat_start, repeat_end, teachers, ...rest} = store.current;
|
||||
if (!kecheng_name) {
|
||||
let { clazz_name, students, course_sections, clazz_repeat, start_from, end_by, is_repeat, instance, has_root, repeat_start, repeat_end, teachers, ...rest} = store.current;
|
||||
if (!clazz_name) {
|
||||
showFailToast("请输入课程名称!")
|
||||
return false
|
||||
}
|
||||
@@ -202,9 +204,9 @@ export default function useKecheng() {
|
||||
showFailToast("请为重复课程选择重复时间!")
|
||||
return false;
|
||||
}
|
||||
kecheng_repeat = {
|
||||
...kecheng_repeat,
|
||||
start_from, end_by, repeat_status: KechengRepeatStatuses.OnGoing,
|
||||
clazz_repeat = {
|
||||
...clazz_repeat,
|
||||
start_from, end_by, repeat_status: ClazzRepeatStatuses.OnGoing,
|
||||
repeat_start: formatDate(repeat_start, DateFormatter.DateTimeSave),
|
||||
repeat_end: formatDate(repeat_end, DateFormatter.DateTimeSave),
|
||||
repeat_cycle_days: (new Date(repeat_end).valueOf() - new Date(repeat_start).valueOf()) / (24 * 3600 * 1000)
|
||||
@@ -231,17 +233,17 @@ export default function useKecheng() {
|
||||
});
|
||||
|
||||
load_start()
|
||||
let data = {...rest, kecheng_name, students, start_from, end_by, is_repeat, kecheng_repeat, course_sections, duration, teachers, kecheng_status: KechengStatuses.Open};
|
||||
let data = {...rest, clazz_name, students, start_from, end_by, is_repeat, clazz_repeat, course_sections, duration, teachers, clazz_status: ClazzStatuses.Open};
|
||||
let res: any;
|
||||
if (rest.id) {
|
||||
res = await request({url: "/api/v1/kc/update_kecheng", method: "POST", data})
|
||||
res = await request({url: "/api/v1/clazz/update", method: "POST", data})
|
||||
if (res.r && is_repeat) {
|
||||
res = await request({url: "/api/v1/kc/update_kecheng_repeat", method: "POST", data: kecheng_repeat})
|
||||
res = await request({url: "/api/v1/clazz/repeat/update", method: "POST", data: clazz_repeat})
|
||||
}
|
||||
} else {
|
||||
// set created by
|
||||
data.created_by = hty_id;
|
||||
res = await request({url: "/api/v1/kc/create_kecheng_with_kecheng_repeat", method: "POST", data})
|
||||
res = await request({url: "/api/v1/clazz/create_with_repeat", method: "POST", data})
|
||||
}
|
||||
const {r, d, e} = res
|
||||
load_done()
|
||||
@@ -254,7 +256,7 @@ export default function useKecheng() {
|
||||
|
||||
let teacher_name = teachers?.val?.users?.vals.map(t => t.real_name).filter(x => x).join(", ")
|
||||
let payload: NotifyParam = {
|
||||
kecheng_id: store.current.id, kecheng_name: store.current.kecheng_name, teacher_name,
|
||||
clazz_id: store.current.id, clazz_name: store.current.clazz_name, teacher_name,
|
||||
start_from: start_from.replace("T", " ").replace(/:00$/, ""), end_by: end_by.split("T")[1].replace(/:00$/, ""),
|
||||
}
|
||||
// notify assist teacher
|
||||
@@ -262,17 +264,17 @@ export default function useKecheng() {
|
||||
teachers?.val?.users?.vals.forEach(t => {
|
||||
// not notify creator
|
||||
if (t.user_id !== (store.current.created_by || hty_id)) {
|
||||
notify({ ...payload, hty_id: t.user_id, student_name, notify_type: NotifyTypes.KechengCreateOrUpdate, } as NotifyParam, HtyBaseRoles.TEACHER)
|
||||
notify({ ...payload, hty_id: t.user_id, student_name, notify_type: NotifyTypes.ClazzCreateOrUpdate, } as NotifyParam, HtyBaseRoles.TEACHER)
|
||||
}
|
||||
})
|
||||
students?.val?.users?.vals.forEach(s => {
|
||||
notify({ ...payload, hty_id: s.user_id, student_name: s.real_name, notify_type: NotifyTypes.KechengCreateOrUpdate } as NotifyParam, HtyBaseRoles.STUDENT)
|
||||
notify({ ...payload, hty_id: s.user_id, student_name: s.real_name, notify_type: NotifyTypes.ClazzCreateOrUpdate } as NotifyParam, HtyBaseRoles.STUDENT)
|
||||
})
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
async function setDakasForKC(daka: Daka) {
|
||||
async function setDakasForClazz(daka: Daka) {
|
||||
try {
|
||||
let {dakas, ...rest} = store.current;
|
||||
if (dakas?.vals.length && !dakas.vals.some(x => x.id === daka.id)) {
|
||||
@@ -281,21 +283,21 @@ export default function useKecheng() {
|
||||
dakas = {vals: [daka]}
|
||||
}
|
||||
load_start()
|
||||
const { r, d, e} = await request({url: "/api/v1/kc/update_kecheng", method: "POST", data: {...rest, dakas}})
|
||||
const { r, d, e} = await request({url: "/api/v1/clazz/update", method: "POST", data: {...rest, dakas}})
|
||||
load_done()
|
||||
if (r) {
|
||||
// reset hanging to force data refresh
|
||||
store.hanging = false;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('update kecheng failed...', e)
|
||||
console.log('update clazz failed...', e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function createInstance(instance: Kecheng, is_delete?: boolean) {
|
||||
let { kecheng_name, students, start_from, end_by, has_root, teachers, ...rest} = instance;
|
||||
if (!kecheng_name) {
|
||||
async function createInstance(instance: Clazz, is_delete?: boolean) {
|
||||
let { clazz_name, students, start_from, end_by, has_root, teachers, ...rest} = instance;
|
||||
if (!clazz_name) {
|
||||
showFailToast("请输入课程名称!")
|
||||
return false
|
||||
}
|
||||
@@ -317,8 +319,8 @@ export default function useKecheng() {
|
||||
teachers.val.users.vals.push({user_id: hty_id, real_name})
|
||||
}
|
||||
load_start()
|
||||
let data = {...rest, kecheng_name, is_delete, students, start_from, end_by, duration, created_by: hty_id, teachers, kecheng_status: KechengStatuses.Open};
|
||||
const {r, d, e} = await request({url: "/api/v1/kc/create_kecheng_with_kecheng_repeat", method: "POST", data})
|
||||
let data = {...rest, clazz_name, is_delete, students, start_from, end_by, duration, created_by: hty_id, teachers, clazz_status: ClazzStatuses.Open};
|
||||
const {r, d, e} = await request({url: "/api/v1/clazz/create_with_repeat", method: "POST", data})
|
||||
load_done()
|
||||
if (!r) {
|
||||
showFailToast(e);
|
||||
@@ -331,10 +333,10 @@ export default function useKecheng() {
|
||||
|
||||
let teacher_name = teachers?.val?.users?.vals.map(t => t.real_name).join(", ")
|
||||
let payload: NotifyParam = {
|
||||
kecheng_id: d.id, kecheng_name, teacher_name,
|
||||
clazz_id: d.id, clazz_name: clazz_name, teacher_name,
|
||||
start_from: start_from.replace("T", " ").replace(/:00$/, ""), end_by: end_by.split("T")[1].replace(/:00$/, ""),
|
||||
}
|
||||
let notify_type = is_delete ? NotifyTypes.KechengDelete : NotifyTypes.KechengCreateOrUpdate;
|
||||
let notify_type = is_delete ? NotifyTypes.ClazzDelete : NotifyTypes.ClazzCreateOrUpdate;
|
||||
// notify assist teacher
|
||||
let student_name = students?.val?.users?.vals.map(x => x.real_name).join(", ")
|
||||
teachers?.val?.users?.vals.forEach(t => {
|
||||
@@ -368,16 +370,16 @@ export default function useKecheng() {
|
||||
let {has_root, repeat_start, repeat_end, instance, ...rest} = store.current;
|
||||
load_start()
|
||||
const {r, d, e} = await request({
|
||||
url: "/api/v1/kc/update_kecheng", method: "POST", data: {...rest, is_delete: true}
|
||||
url: "/api/v1/clazz/update", method: "POST", data: {...rest, is_delete: true}
|
||||
})
|
||||
load_done()
|
||||
if (!r) {
|
||||
showFailToast(e)
|
||||
} else {
|
||||
let { id, teachers, students, kecheng_name, start_from, end_by, created_by} = store.current;
|
||||
let { id, teachers, students, clazz_name, start_from, end_by, created_by} = store.current;
|
||||
let teacher_name = teachers?.val?.users?.vals.map(t => t.real_name).join(", ")
|
||||
let payload: NotifyParam = {
|
||||
kecheng_id: id, kecheng_name, teacher_name,
|
||||
clazz_id: id, clazz_name: clazz_name, teacher_name,
|
||||
start_from: start_from.replace("T", " ").replace(/:00$/, ""),
|
||||
end_by: end_by.split("T")[1].replace(/:00$/, ""),
|
||||
}
|
||||
@@ -386,18 +388,45 @@ export default function useKecheng() {
|
||||
teachers?.val?.users?.vals.forEach(t => {
|
||||
// not notify creator
|
||||
if (t.user_id !== created_by) {
|
||||
notify({ ...payload, hty_id: t.user_id, student_name, notify_type: NotifyTypes.KechengDelete, } as NotifyParam, HtyBaseRoles.TEACHER)
|
||||
notify({ ...payload, hty_id: t.user_id, student_name, notify_type: NotifyTypes.ClazzDelete, } as NotifyParam, HtyBaseRoles.TEACHER)
|
||||
}
|
||||
})
|
||||
students?.val?.users?.vals.forEach(s => {
|
||||
notify({ ...payload, hty_id: s.user_id, student_name: s.real_name, notify_type: NotifyTypes.KechengDelete } as NotifyParam, HtyBaseRoles.STUDENT)
|
||||
notify({ ...payload, hty_id: s.user_id, student_name: s.real_name, notify_type: NotifyTypes.ClazzDelete } as NotifyParam, HtyBaseRoles.STUDENT)
|
||||
})
|
||||
}
|
||||
return Promise.resolve(r)
|
||||
}
|
||||
|
||||
async function find_clazz_attendance_by_clazz_id(clazz_id: string): Promise<ClazzAttendance[] | null> {
|
||||
const { r, d, e } = await request({
|
||||
url: `/api/v1/clazz/attendance/${encodeURIComponent(clazz_id)}`,
|
||||
method: "GET",
|
||||
});
|
||||
if (r) {
|
||||
return d as ClazzAttendance[];
|
||||
}
|
||||
showFailToast(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
async function batch_save_clazz_attendance(payload: ReqBatchClazzAttendance): Promise<boolean> {
|
||||
load_start();
|
||||
const { r, e } = await request({
|
||||
url: "/api/v1/clazz/batch_save_attendance",
|
||||
method: "POST",
|
||||
data: payload,
|
||||
});
|
||||
load_done();
|
||||
if (!r) {
|
||||
showFailToast(e);
|
||||
}
|
||||
return !!r;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
store, query, query_repeats, createOrUpdate, removeCurrent, createInstance, notify, setDakasForKC, query_for_subsidiaries, query_repeats_for_subsidiaries
|
||||
store, query, query_repeats, createOrUpdate, removeCurrent, createInstance, notify, setDakasForClazz, query_for_subsidiaries, query_repeats_for_subsidiaries,
|
||||
find_clazz_attendance_by_clazz_id, batch_save_clazz_attendance,
|
||||
}
|
||||
}
|
||||
+8
-7
@@ -9,7 +9,8 @@ import {
|
||||
DakaScope,
|
||||
HtyBaseRoles,
|
||||
HtyRoles,
|
||||
JihuaQueryParam, Kecheng,
|
||||
Clazz,
|
||||
JihuaQueryParam,
|
||||
Lianxi, MultiVals,
|
||||
NotifyParam,
|
||||
NotifyTypes,
|
||||
@@ -95,14 +96,14 @@ export default function useDaka() {
|
||||
store.list = [];
|
||||
}
|
||||
let [list, pages, total] = d;
|
||||
let kcs = await queryKechengs(list.map((x: Daka) => x.id))
|
||||
let dict: {[key: string]: Kecheng} = {};
|
||||
let kcs = await queryClazzByDakaIds(list.map((x: Daka) => x.id))
|
||||
let dict: {[key: string]: Clazz} = {};
|
||||
kcs.forEach(kc => {
|
||||
kc.dakas?.vals.forEach(x => {
|
||||
dict[x.id as string] = kc;
|
||||
})
|
||||
})
|
||||
store.list = [...store.list, ...list.map((x: Daka) => ({...convert(x), kecheng: dict[x.id], end_date: getEndDate(x)}))];
|
||||
store.list = [...store.list, ...list.map((x: Daka) => ({...convert(x), clazz: dict[x.id], end_date: getEndDate(x)}))];
|
||||
store.total = total;
|
||||
store.pages = pages;
|
||||
} else {
|
||||
@@ -112,10 +113,10 @@ export default function useDaka() {
|
||||
}
|
||||
|
||||
|
||||
async function queryKechengs(daka_ids: string[]): Promise<Kecheng[]> {
|
||||
async function queryClazzByDakaIds(daka_ids: string[]): Promise<Clazz[]> {
|
||||
load_start()
|
||||
const {r, d, e} = await request({
|
||||
url: '/api/v1/kc/find_kechengs_by_daka_ids', data: daka_ids, method: 'POST'
|
||||
url: '/api/v1/clazz/find_by_daka_ids', data: daka_ids, method: 'POST'
|
||||
});
|
||||
load_done()
|
||||
if (r) {
|
||||
@@ -290,7 +291,7 @@ export default function useDaka() {
|
||||
load_done();
|
||||
return 0;
|
||||
}
|
||||
let { end_date, teachers, students, kecheng, ...rest } = data;
|
||||
let { end_date, teachers, students, clazz, ...rest } = data;
|
||||
clean_teachers(teachers)
|
||||
const {r, e} = await request({
|
||||
url: `/api/v1/ws/update_daka`,
|
||||
|
||||
+76
-49
@@ -198,7 +198,7 @@ export enum CommentRefTypes {
|
||||
Jihua = 'JIHUA',
|
||||
Daka = 'DAKA',
|
||||
ResourceNote = 'RESOURCE_NOTE',
|
||||
Kecheng = 'KECHENG',
|
||||
Clazz = 'CLAZZ',
|
||||
}
|
||||
|
||||
export interface Comment {
|
||||
@@ -466,7 +466,7 @@ export interface Daka {
|
||||
groups?: import('@authcore/commons').UserGroup[];
|
||||
teachers?: import('@authcore/commons').MultiVals<TeacherSummary>;
|
||||
students?: import('@authcore/commons').SingleVal<import('@authcore/commons').UserGroup>;
|
||||
kecheng?: Kecheng;
|
||||
clazz?: Clazz;
|
||||
is_yanqi?: boolean;
|
||||
}
|
||||
|
||||
@@ -497,7 +497,7 @@ export enum PickTargets {
|
||||
USER_GROUP = 'USER_GROUP',
|
||||
COURSE_SECTION = 'COURSE_SECTION',
|
||||
COURSE_GROUP = 'COURSE_GROUP',
|
||||
KECHENG = 'KECHENG',
|
||||
CLAZZ = 'CLAZZ',
|
||||
}
|
||||
|
||||
export interface LatitudePos {
|
||||
@@ -563,7 +563,7 @@ export interface PoolData {
|
||||
current_role?: string;
|
||||
hide_bottom_tab?: boolean;
|
||||
scoring_audio?: RefResource;
|
||||
kecheng_state?: unknown;
|
||||
clazz_state?: unknown;
|
||||
course_sections?: CourseSection[];
|
||||
teachers?: import('@authcore/commons').SingleVal<import('@authcore/commons').UserGroup>;
|
||||
students?: import('@authcore/commons').SingleVal<import('@authcore/commons').UserGroup>;
|
||||
@@ -576,31 +576,43 @@ export enum TimeUnits {
|
||||
SECOND = 'SECOND',
|
||||
}
|
||||
|
||||
export enum KechengStatuses {
|
||||
export enum ClazzStatuses {
|
||||
Open = 'OPEN',
|
||||
}
|
||||
|
||||
export enum KechengRepeatStatuses {
|
||||
export enum ClazzRepeatStatuses {
|
||||
OnGoing = 'ON_GOING',
|
||||
}
|
||||
|
||||
export interface KechengUser {
|
||||
export interface ClazzRepeat {
|
||||
id: string;
|
||||
clazz_id: string;
|
||||
start_from?: string | Date;
|
||||
end_by?: string | Date;
|
||||
repeat_start: string | Date;
|
||||
repeat_end?: string | Date;
|
||||
repeat_cycle_days: number;
|
||||
repeat_status: ClazzRepeatStatuses;
|
||||
latest_clazz_created_at?: string | Date;
|
||||
}
|
||||
|
||||
export interface ClazzUser {
|
||||
id: string;
|
||||
user_id: string;
|
||||
kecheng_id: string;
|
||||
kecheng_status: KechengStatuses;
|
||||
clazz_id: string;
|
||||
clazz_status: ClazzStatuses;
|
||||
user_type: import('@authcore/commons').HtyBaseRoles;
|
||||
}
|
||||
|
||||
export interface Kecheng {
|
||||
export interface Clazz {
|
||||
id: string;
|
||||
kecheng_name: string;
|
||||
kecheng_desc: string;
|
||||
kecheng_status: KechengStatuses;
|
||||
clazz_name: string;
|
||||
clazz_desc: string;
|
||||
clazz_status: ClazzStatuses;
|
||||
start_from: string | Date;
|
||||
end_by: string | Date;
|
||||
duration: number;
|
||||
kecheng_type: string;
|
||||
clazz_type: string;
|
||||
root_id: string;
|
||||
parent_id: string;
|
||||
teachers: import('@authcore/commons').SingleVal<import('@authcore/commons').UserGroup>;
|
||||
@@ -610,62 +622,77 @@ export interface Kecheng {
|
||||
dakas?: import('@authcore/commons').MultiVals<Daka>;
|
||||
jihuas?: import('@authcore/commons').MultiVals<Jihua>;
|
||||
is_delete?: boolean;
|
||||
kecheng_repeat?: KechengRepeat;
|
||||
clazz_repeat?: ClazzRepeat;
|
||||
is_repeat: boolean;
|
||||
repeat_start?: string | Date;
|
||||
repeat_end?: string | Date;
|
||||
instance?: Kecheng;
|
||||
instance?: Clazz;
|
||||
has_root?: boolean;
|
||||
is_notified?: boolean;
|
||||
course_sections?: import('@authcore/commons').MultiVals<CourseSection>;
|
||||
}
|
||||
|
||||
export interface KechengWithRepeat {
|
||||
kc_id: string;
|
||||
kc_kecheng_name: string;
|
||||
kc_kecheng_desc: string;
|
||||
kc_kecheng_status: KechengStatuses;
|
||||
kc_start_from: string | Date;
|
||||
kc_end_by: string | Date;
|
||||
kc_duration: number;
|
||||
kc_kecheng_type: string;
|
||||
kc_root_id: string;
|
||||
kc_parent_id: string;
|
||||
kc_teachers: import('@authcore/commons').SingleVal<import('@authcore/commons').UserGroup>;
|
||||
kc_students: import('@authcore/commons').SingleVal<import('@authcore/commons').UserGroup>;
|
||||
kc_created_by: string;
|
||||
kc_created_at: string | Date;
|
||||
kc_dakas?: import('@authcore/commons').MultiVals<Daka>;
|
||||
kc_jihuas?: import('@authcore/commons').MultiVals<Jihua>;
|
||||
kc_is_delete?: boolean;
|
||||
kc_is_repeat: boolean;
|
||||
/** 与后端 ReqClazzWithRepeat(扁平 join)字段一致:clz_* 主表,re_* 重复规则 */
|
||||
export interface ClazzWithRepeat {
|
||||
clz_id: string;
|
||||
clz_clazz_name: string;
|
||||
clz_clazz_desc: string;
|
||||
clz_clazz_status: ClazzStatuses;
|
||||
clz_start_from: string | Date;
|
||||
clz_end_by: string | Date;
|
||||
clz_duration: number;
|
||||
clz_clazz_type: string;
|
||||
clz_root_id: string;
|
||||
clz_parent_id: string;
|
||||
clz_teachers: import('@authcore/commons').SingleVal<import('@authcore/commons').UserGroup>;
|
||||
clz_students: import('@authcore/commons').SingleVal<import('@authcore/commons').UserGroup>;
|
||||
clz_created_by: string;
|
||||
clz_created_at: string | Date;
|
||||
clz_dakas?: import('@authcore/commons').MultiVals<Daka>;
|
||||
clz_jihuas?: import('@authcore/commons').MultiVals<Jihua>;
|
||||
clz_is_delete?: boolean;
|
||||
clz_is_repeat: boolean;
|
||||
re_id: string;
|
||||
re_kecheng_id: string;
|
||||
re_clazz_id: string;
|
||||
re_start_from?: string | Date;
|
||||
re_end_by?: string | Date;
|
||||
re_repeat_start: string | Date;
|
||||
re_repeat_end?: string | Date;
|
||||
re_repeat_cycle_days: number;
|
||||
re_repeat_status: KechengRepeatStatuses;
|
||||
re_repeat_status: ClazzRepeatStatuses;
|
||||
}
|
||||
|
||||
export interface KechengRepeat {
|
||||
/** 排课消课记录(对应 htykc.clazz_attendance) */
|
||||
export interface ClazzAttendance {
|
||||
id: string;
|
||||
kecheng_id: string;
|
||||
start_from?: string | Date;
|
||||
end_by?: string | Date;
|
||||
repeat_start: string | Date;
|
||||
repeat_end?: string | Date;
|
||||
repeat_cycle_days: number;
|
||||
repeat_status: KechengRepeatStatuses;
|
||||
latest_kc_created_at?: string | Date;
|
||||
clazz_id: string;
|
||||
student_id: string;
|
||||
course_hour_package_id?: string | null;
|
||||
status: string;
|
||||
deducted_hours: number;
|
||||
sign_time: string;
|
||||
sign_method?: string | null;
|
||||
created_at: string;
|
||||
created_by?: string | null;
|
||||
is_delete?: boolean | null;
|
||||
}
|
||||
|
||||
export interface RepeatKecheng {
|
||||
rootKecheng: Kecheng;
|
||||
rpeat: KechengRepeat;
|
||||
export interface ReqClazzAttendanceItem {
|
||||
student_id: string;
|
||||
status: string;
|
||||
deducted_hours: number;
|
||||
sign_method?: string | null;
|
||||
course_hour_package_id?: string | null;
|
||||
}
|
||||
|
||||
export interface ReqBatchClazzAttendance {
|
||||
clazz_id: string;
|
||||
items: ReqClazzAttendanceItem[];
|
||||
}
|
||||
|
||||
/** 日历重复行:扁平 clazz + 当周实例 */
|
||||
export type ClazzRepeatRow = Clazz & { instance?: Clazz };
|
||||
|
||||
export interface ScoreShifan {
|
||||
shifan_url?: string;
|
||||
audio_type?: string;
|
||||
|
||||
@@ -71,7 +71,7 @@ axiosInstance.interceptors.request.use((options) => {
|
||||
const cozePath = '/api/v1/coze' + url.slice(5);
|
||||
// @ts-ignore
|
||||
url = import.meta.env.DEV ? cozePath : (AI_SERVER + cozePath);
|
||||
} else if (url?.startsWith('/api/v1/kc')) {
|
||||
} else if (url?.startsWith('/api/v1/clazz')) {
|
||||
// @ts-ignore
|
||||
url = KC_SERVER + url;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user