feat: 添加教师团队管理功能,包括搜索、添加和删除教师团队成员
This commit is contained in:
parent
b05f954923
commit
9a36188322
@ -19,6 +19,8 @@ export interface ITeacher {
|
|||||||
employeeId: string;
|
employeeId: string;
|
||||||
schoolId: number;
|
schoolId: number;
|
||||||
collegeId: number;
|
collegeId: number;
|
||||||
|
schoolName: string;
|
||||||
|
collegeName: string;
|
||||||
sex: number;
|
sex: number;
|
||||||
email: string;
|
email: string;
|
||||||
phonenumber: string;
|
phonenumber: string;
|
||||||
@ -143,6 +145,22 @@ export const deleteCourseResource = async (resourceId: number) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const addTeacherToCourse = async (params: {
|
||||||
|
courseId: number;
|
||||||
|
teacherId: number;
|
||||||
|
}) => {
|
||||||
|
return await http<IResponse>(`/system/teacherteam`, {
|
||||||
|
method: "POST",
|
||||||
|
body: params,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deleteTeacherTeamRecord = async (recordId: number) => {
|
||||||
|
return await http<IResponse>(`/system/teacherteam/${recordId}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const getTeacherTeamByCourse = async (courseId: number) => {
|
export const getTeacherTeamByCourse = async (courseId: number) => {
|
||||||
return await http<
|
return await http<
|
||||||
IResponse<{
|
IResponse<{
|
||||||
|
14
api/user.ts
14
api/user.ts
@ -35,3 +35,17 @@ export const userProfile = async () => {
|
|||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const userSearch = async (pararms: {
|
||||||
|
searchType: "student" | "teacher";
|
||||||
|
keyword: string;
|
||||||
|
}) => {
|
||||||
|
return await http<
|
||||||
|
IResponse & {
|
||||||
|
data: IUser[];
|
||||||
|
}
|
||||||
|
>(`/system/user/search`, {
|
||||||
|
method: "GET",
|
||||||
|
query: pararms,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -7,7 +7,7 @@ defineProps<{
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
delete: [teacherId: number];
|
delete: [recordId: number];
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -17,11 +17,12 @@ const emit = defineEmits<{
|
|||||||
class="absolute top-0 right-0 flex flex-col gap-1 invisible group-hover/member-card:visible"
|
class="absolute top-0 right-0 flex flex-col gap-1 invisible group-hover/member-card:visible"
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
|
v-if="!isCurrentUser"
|
||||||
variant="link"
|
variant="link"
|
||||||
size="icon"
|
size="icon"
|
||||||
@click.stop="emit('delete', member.teacherId)"
|
@click="emit('delete', member.id)"
|
||||||
>
|
>
|
||||||
<Icon name="tabler:trash" size="16px" class="text-red-500" />
|
<Icon name="tabler:logout" size="20px" class="text-red-500" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -46,10 +47,10 @@ const emit = defineEmits<{
|
|||||||
工号:{{ member.teacher.employeeId || "未知" }}
|
工号:{{ member.teacher.employeeId || "未知" }}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xs text-muted-foreground/80">
|
<p class="text-xs text-muted-foreground/80">
|
||||||
{{ member.teacher.schoolId || "未知学校" }}
|
{{ member.teacher.schoolName || "未知学校" }}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xs text-muted-foreground/80">
|
<p class="text-xs text-muted-foreground/80">
|
||||||
{{ member.teacher.collegeId || "未知学院" }}
|
{{ member.teacher.collegeName || "未知学院" }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,6 +23,7 @@ export default defineNuxtConfig({
|
|||||||
"pinia-plugin-persistedstate",
|
"pinia-plugin-persistedstate",
|
||||||
"dayjs-nuxt",
|
"dayjs-nuxt",
|
||||||
"@formkit/auto-animate",
|
"@formkit/auto-animate",
|
||||||
|
"@vueuse/nuxt",
|
||||||
],
|
],
|
||||||
|
|
||||||
icon: {
|
icon: {
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
"@nuxtjs/color-mode": "^3.5.2",
|
"@nuxtjs/color-mode": "^3.5.2",
|
||||||
"@nuxtjs/tailwindcss": "^6.13.2",
|
"@nuxtjs/tailwindcss": "^6.13.2",
|
||||||
"@pinia/nuxt": "^0.10.1",
|
"@pinia/nuxt": "^0.10.1",
|
||||||
|
"@vueuse/nuxt": "^13.0.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"dayjs-nuxt": "^2.1.11",
|
"dayjs-nuxt": "^2.1.11",
|
||||||
"pinia-plugin-persistedstate": "^4.2.0",
|
"pinia-plugin-persistedstate": "^4.2.0",
|
||||||
|
@ -1,7 +1,43 @@
|
|||||||
<script lang="ts" setup></script>
|
<script lang="ts" setup>
|
||||||
|
import { getCourseDetail } from "~/api/course";
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
requiresAuth: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
params: { id: courseId },
|
||||||
|
} = useRoute();
|
||||||
|
|
||||||
|
// const loginState = useLoginState();
|
||||||
|
const course = await getCourseDetail(courseId as string);
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>Classes</div>
|
<div class="flex flex-col gap-4 px-4 py-2">
|
||||||
|
<div class="flex justify-between items-start">
|
||||||
|
<h1 class="text-xl font-medium">
|
||||||
|
课程班级管理
|
||||||
|
<span class="block text-sm text-muted-foreground">
|
||||||
|
课程负责人:{{ course.data.teacherName || "未知" }}
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<Button variant="secondary" size="sm" class="flex items-center gap-1">
|
||||||
|
<Icon name="tabler:plus" size="16px" />
|
||||||
|
<span>创建班级</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="false"></div>
|
||||||
|
<EmptyScreen
|
||||||
|
v-else
|
||||||
|
title="暂无班级"
|
||||||
|
description="课程下没有班级,请创建新的班级"
|
||||||
|
icon="fluent-color:people-list-24"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@ -1,21 +1,99 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { getCourseDetail, getTeacherTeamByCourse } from "~/api/course";
|
import { toast } from "vue-sonner";
|
||||||
|
import { userSearch } from "~/api";
|
||||||
|
import {
|
||||||
|
addTeacherToCourse,
|
||||||
|
deleteTeacherTeamRecord,
|
||||||
|
getCourseDetail,
|
||||||
|
getTeacherTeamByCourse,
|
||||||
|
} from "~/api/course";
|
||||||
|
import type { FetchError } from "~/types";
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const loginState = useLoginState();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
params: { id: courseId },
|
params: { id: courseId },
|
||||||
} = useRoute();
|
} = useRoute();
|
||||||
|
|
||||||
|
const loginState = useLoginState();
|
||||||
const course = await getCourseDetail(courseId as string);
|
const course = await getCourseDetail(courseId as string);
|
||||||
|
|
||||||
const { data: teacherTeam } = useAsyncData(() =>
|
const { data: teacherTeam, refresh: refreshTeacherTeam } = useAsyncData(() =>
|
||||||
getTeacherTeamByCourse(parseInt(courseId as string))
|
getTeacherTeamByCourse(parseInt(courseId as string))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const searchKeyword = ref("");
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: searchResults,
|
||||||
|
refresh: refreshSearch,
|
||||||
|
clear: clearSearch,
|
||||||
|
} = useAsyncData(
|
||||||
|
() =>
|
||||||
|
userSearch({
|
||||||
|
searchType: "teacher",
|
||||||
|
keyword: searchKeyword.value,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
immediate: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// watch searchKeyword and refresh search results, with debounce
|
||||||
|
const triggerSearch = useDebounceFn(() => {
|
||||||
|
if (searchKeyword.value.length > 0) {
|
||||||
|
refreshSearch();
|
||||||
|
} else {
|
||||||
|
clearSearch();
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
watch(searchKeyword, (newValue) => {
|
||||||
|
if (newValue.length > 0) {
|
||||||
|
triggerSearch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const isInTeam = (userId: number) => {
|
||||||
|
return teacherTeam?.value?.data?.some((item) => item.teacherId === userId);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onAddTeacherToCourse = (teacherId: number) => {
|
||||||
|
toast.promise(
|
||||||
|
addTeacherToCourse({
|
||||||
|
courseId: parseInt(courseId as string),
|
||||||
|
teacherId,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
loading: "正在添加教师...",
|
||||||
|
success: () => {
|
||||||
|
refreshTeacherTeam();
|
||||||
|
return "添加教师成功";
|
||||||
|
},
|
||||||
|
error: (error: FetchError) => {
|
||||||
|
if (error.statusCode === 409) {
|
||||||
|
return "该教师已在团队中";
|
||||||
|
}
|
||||||
|
return `添加教师失败:${error.message}`;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDeleteTeacher = (recordId: number) => {
|
||||||
|
toast.promise(deleteTeacherTeamRecord(recordId), {
|
||||||
|
loading: "正在移出教师...",
|
||||||
|
success: () => {
|
||||||
|
refreshTeacherTeam();
|
||||||
|
return "移出教师成功";
|
||||||
|
},
|
||||||
|
error: (error: FetchError) => {
|
||||||
|
return `移出教师失败:${error.message}`;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -28,12 +106,106 @@ const { data: teacherTeam } = useAsyncData(() =>
|
|||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<Button variant="secondary" size="sm" class="flex items-center gap-1">
|
<Popover>
|
||||||
<Icon name="tabler:plus" size="16px" />
|
<PopoverTrigger as-child>
|
||||||
<span>添加教师</span>
|
<Button
|
||||||
</Button>
|
variant="secondary"
|
||||||
|
size="sm"
|
||||||
|
class="flex items-center gap-1"
|
||||||
|
>
|
||||||
|
<Icon name="tabler:plus" size="16px" />
|
||||||
|
<span>添加教师</span>
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent class="w-96" :align="'end'">
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<FormField v-slot="{ componentField }" name="keyword">
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>搜索教师</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
v-bind="componentField"
|
||||||
|
v-model="searchKeyword"
|
||||||
|
type="text"
|
||||||
|
placeholder="搜索工号/姓名/手机号"
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormDescription>
|
||||||
|
<p class="text-xs">
|
||||||
|
搜索教师工号/姓名/手机号,然后添加到团队中
|
||||||
|
</p>
|
||||||
|
</FormDescription>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
</FormField>
|
||||||
|
<hr />
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<p class="text-sm text-muted-foreground">搜索结果</p>
|
||||||
|
<div
|
||||||
|
v-if="searchResults?.data && searchResults.data.length > 0"
|
||||||
|
class="flex flex-col gap-2"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="user in searchResults.data"
|
||||||
|
:key="user.userId"
|
||||||
|
class="flex justify-between items-center gap-2"
|
||||||
|
>
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<Avatar class="w-12 h-12 text-base">
|
||||||
|
<AvatarImage
|
||||||
|
:src="user.avatar || ''"
|
||||||
|
:alt="user.userName"
|
||||||
|
/>
|
||||||
|
<AvatarFallback class="rounded-lg">
|
||||||
|
{{ user.userName.slice(0, 2).toUpperCase() }}
|
||||||
|
</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
<h1
|
||||||
|
class="text-sm font-medium text-ellipsis line-clamp-1"
|
||||||
|
>
|
||||||
|
{{ user.userName || "未知教师" }}
|
||||||
|
</h1>
|
||||||
|
<p class="text-xs text-muted-foreground/80">
|
||||||
|
工号:{{ user.employeeId || "未知" }}
|
||||||
|
</p>
|
||||||
|
<p class="text-xs text-muted-foreground/80">
|
||||||
|
{{ user.collegeName || "未知学院" }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
size="sm"
|
||||||
|
class="flex items-center gap-1"
|
||||||
|
:disabled="isInTeam(user.id!)"
|
||||||
|
@click="onAddTeacherToCourse(user.id!)"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
v-if="!isInTeam(user.id!)"
|
||||||
|
name="tabler:plus"
|
||||||
|
size="16px"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
{{ isInTeam(user.id!) ? "已在团队" : "添加" }}
|
||||||
|
</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<EmptyScreen
|
||||||
|
v-else
|
||||||
|
title="没有搜索结果"
|
||||||
|
description="没有找到符合条件的教师"
|
||||||
|
icon="fluent-color:people-list-24"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="teacherTeam?.data && teacherTeam.data.length > 0"
|
v-if="teacherTeam?.data && teacherTeam.data.length > 0"
|
||||||
class="grid gap-6 grid-cols-2 sm:grid-cols-3 2xl:grid-cols-5"
|
class="grid gap-6 grid-cols-2 sm:grid-cols-3 2xl:grid-cols-5"
|
||||||
@ -43,6 +215,7 @@ const { data: teacherTeam } = useAsyncData(() =>
|
|||||||
:key="member.teacherId"
|
:key="member.teacherId"
|
||||||
:is-current-user="loginState.user?.userId === member.teacherId"
|
:is-current-user="loginState.user?.userId === member.teacherId"
|
||||||
:member
|
:member
|
||||||
|
@delete="onDeleteTeacher"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<EmptyScreen
|
<EmptyScreen
|
||||||
@ -51,9 +224,6 @@ const { data: teacherTeam } = useAsyncData(() =>
|
|||||||
description="请添加教师作为团队成员"
|
description="请添加教师作为团队成员"
|
||||||
icon="fluent-color:people-list-24"
|
icon="fluent-color:people-list-24"
|
||||||
/>
|
/>
|
||||||
<DevOnly>
|
|
||||||
<pre>{{ teacherTeam }}</pre>
|
|
||||||
</DevOnly>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
20
pnpm-lock.yaml
generated
20
pnpm-lock.yaml
generated
@ -93,6 +93,9 @@ importers:
|
|||||||
'@pinia/nuxt':
|
'@pinia/nuxt':
|
||||||
specifier: ^0.10.1
|
specifier: ^0.10.1
|
||||||
version: 0.10.1(magicast@0.3.5)(pinia@3.0.1(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))
|
version: 0.10.1(magicast@0.3.5)(pinia@3.0.1(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))
|
||||||
|
'@vueuse/nuxt':
|
||||||
|
specifier: ^13.0.0
|
||||||
|
version: 13.0.0(magicast@0.3.5)(nuxt@3.16.1(@parcel/watcher@2.5.1)(db0@0.3.1)(eslint@9.23.0(jiti@2.4.2))(ioredis@5.6.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.37.0)(terser@5.39.0)(typescript@5.8.2)(vite@6.2.3(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))
|
||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.13
|
specifier: ^1.11.13
|
||||||
version: 1.11.13
|
version: 1.11.13
|
||||||
@ -1412,6 +1415,12 @@ packages:
|
|||||||
'@vueuse/metadata@13.0.0':
|
'@vueuse/metadata@13.0.0':
|
||||||
resolution: {integrity: sha512-TRNksqmvtvqsuHf7bbgH9OSXEV2b6+M3BSN4LR5oxWKykOFT9gV78+C2/0++Pq9KCp9KQ1OQDPvGlWNQpOb2Mw==}
|
resolution: {integrity: sha512-TRNksqmvtvqsuHf7bbgH9OSXEV2b6+M3BSN4LR5oxWKykOFT9gV78+C2/0++Pq9KCp9KQ1OQDPvGlWNQpOb2Mw==}
|
||||||
|
|
||||||
|
'@vueuse/nuxt@13.0.0':
|
||||||
|
resolution: {integrity: sha512-tVb57PW0aUGMHwvzp4uH2mo8ut3D/3c7DA936E4ValhQq2VMZMCMxaKGz1nE8etFC7p18fVypyzpe8o6CBAYFw==}
|
||||||
|
peerDependencies:
|
||||||
|
nuxt: ^3.0.0 || ^4.0.0-0
|
||||||
|
vue: ^3.5.0
|
||||||
|
|
||||||
'@vueuse/shared@12.8.2':
|
'@vueuse/shared@12.8.2':
|
||||||
resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==}
|
resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==}
|
||||||
|
|
||||||
@ -6162,6 +6171,17 @@ snapshots:
|
|||||||
|
|
||||||
'@vueuse/metadata@13.0.0': {}
|
'@vueuse/metadata@13.0.0': {}
|
||||||
|
|
||||||
|
'@vueuse/nuxt@13.0.0(magicast@0.3.5)(nuxt@3.16.1(@parcel/watcher@2.5.1)(db0@0.3.1)(eslint@9.23.0(jiti@2.4.2))(ioredis@5.6.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.37.0)(terser@5.39.0)(typescript@5.8.2)(vite@6.2.3(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))':
|
||||||
|
dependencies:
|
||||||
|
'@nuxt/kit': 3.16.1(magicast@0.3.5)
|
||||||
|
'@vueuse/core': 13.0.0(vue@3.5.13(typescript@5.8.2))
|
||||||
|
'@vueuse/metadata': 13.0.0
|
||||||
|
local-pkg: 1.1.1
|
||||||
|
nuxt: 3.16.1(@parcel/watcher@2.5.1)(db0@0.3.1)(eslint@9.23.0(jiti@2.4.2))(ioredis@5.6.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.37.0)(terser@5.39.0)(typescript@5.8.2)(vite@6.2.3(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.0))(yaml@2.7.0)
|
||||||
|
vue: 3.5.13(typescript@5.8.2)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- magicast
|
||||||
|
|
||||||
'@vueuse/shared@12.8.2(typescript@5.8.2)':
|
'@vueuse/shared@12.8.2(typescript@5.8.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.5.13(typescript@5.8.2)
|
vue: 3.5.13(typescript@5.8.2)
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
export * from "./user";
|
export * from "./user";
|
||||||
export * from "./course";
|
export * from "./course";
|
||||||
|
|
||||||
|
export type { FetchError } from "ofetch";
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
export type LoginType = "admin" | "teacher" | "student";
|
export type LoginType = "admin" | "teacher" | "student";
|
||||||
|
|
||||||
export interface IUser {
|
export interface IUser {
|
||||||
|
id?: number;
|
||||||
createBy: number;
|
createBy: number;
|
||||||
createTime: Date;
|
createTime: Date;
|
||||||
updateBy: string;
|
updateBy: string;
|
||||||
@ -8,6 +9,11 @@ export interface IUser {
|
|||||||
remark: string;
|
remark: string;
|
||||||
userId: number;
|
userId: number;
|
||||||
deptId: number;
|
deptId: number;
|
||||||
|
collegeName: string;
|
||||||
|
schoolName: string;
|
||||||
|
employeeId: string;
|
||||||
|
schoolId: number;
|
||||||
|
collegeId: number;
|
||||||
userName: string;
|
userName: string;
|
||||||
nickName: string;
|
nickName: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
Loading…
Reference in New Issue
Block a user