Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-resource
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-resource
Commits
fb8b2339
提交
fb8b2339
authored
2月 09, 2026
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 添加账号类型和有效期字段,支持教工和学生的批量导入与管理
上级
e71b0b3f
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
187 行增加
和
45 行删除
+187
-45
学生导入模板.xlsx
public/center_resource/学生导入模板.xlsx
+0
-0
教工导入模板.xlsx
public/center_resource/教工导入模板.xlsx
+0
-0
api.ts
src/modules/admin/staff/api.ts
+12
-1
AddStaff.vue
src/modules/admin/staff/components/AddStaff.vue
+37
-17
ImportStaff.vue
src/modules/admin/staff/components/ImportStaff.vue
+16
-1
List.vue
src/modules/admin/staff/views/List.vue
+25
-0
api.ts
src/modules/admin/student/api.ts
+24
-2
AddStudent.vue
src/modules/admin/student/components/AddStudent.vue
+38
-20
ImportStudent.vue
src/modules/admin/student/components/ImportStudent.vue
+1
-1
UpdateStudent.vue
src/modules/admin/student/components/UpdateStudent.vue
+1
-1
List.vue
src/modules/admin/student/views/List.vue
+33
-2
没有找到文件。
public/center_resource/学生导入模板.xlsx
浏览文件 @
fb8b2339
No preview for this file type
public/center_resource/教工导入模板.xlsx
浏览文件 @
fb8b2339
No preview for this file type
src/modules/admin/staff/api.ts
浏览文件 @
fb8b2339
import
httpRequest
from
'@/utils/axios'
import
httpRequest
from
'@/utils/axios'
// // 获取学生列表
// // 获取学生列表
export
function
getStaffList
(
params
?:
{
name
?:
string
;
organ_id
?:
string
;
page
?:
string
;
[
'per-page'
]?:
string
})
{
export
function
getStaffList
(
params
?:
{
name
?:
string
organ_id
?:
string
account_type
?:
string
status
?:
string
page
?:
string
[
'per-page'
]?:
string
})
{
return
httpRequest
.
get
(
'/api/resource/v1/learning/teacher/list'
,
{
params
})
return
httpRequest
.
get
(
'/api/resource/v1/learning/teacher/list'
,
{
params
})
}
}
// 添加学生
// 添加学生
...
@@ -12,6 +19,8 @@ export function addStaff(data?: {
...
@@ -12,6 +19,8 @@ export function addStaff(data?: {
mobile
:
string
mobile
:
string
role
:
string
role
:
string
email
:
string
email
:
string
account_type
?:
string
account_expired_time
?:
string
})
{
})
{
return
httpRequest
.
post
(
'/api/resource/v1/learning/teacher/create'
,
data
)
return
httpRequest
.
post
(
'/api/resource/v1/learning/teacher/create'
,
data
)
}
}
...
@@ -28,6 +37,8 @@ export function updateStaff(data?: {
...
@@ -28,6 +37,8 @@ export function updateStaff(data?: {
mobile
:
string
mobile
:
string
role
:
string
role
:
string
email
:
string
email
:
string
account_type
?:
string
account_expired_time
?:
string
})
{
})
{
return
httpRequest
.
post
(
'/api/resource/v1/learning/teacher/update'
,
data
)
return
httpRequest
.
post
(
'/api/resource/v1/learning/teacher/update'
,
data
)
}
}
src/modules/admin/staff/components/AddStaff.vue
浏览文件 @
fb8b2339
...
@@ -13,17 +13,17 @@ const ruleFormRef = ref<FormInstance>()
...
@@ -13,17 +13,17 @@ const ruleFormRef = ref<FormInstance>()
const
emit
=
defineEmits
<
Emits
>
()
const
emit
=
defineEmits
<
Emits
>
()
const
props
=
defineProps
({
const
props
=
defineProps
({
isShowStaffDialog
:
{
isShowStaffDialog
:
{
type
:
Boolean
type
:
Boolean
,
},
},
title
:
{
title
:
{
type
:
String
type
:
String
,
},
},
isEdit
:
{
isEdit
:
{
type
:
String
type
:
String
,
},
},
id
:
{
id
:
{
type
:
String
type
:
String
,
}
}
,
})
})
interface
Emits
{
interface
Emits
{
(
e
:
'update:isShowStaffDialog'
,
isShowStaffDialog
:
boolean
):
void
(
e
:
'update:isShowStaffDialog'
,
isShowStaffDialog
:
boolean
):
void
...
@@ -40,7 +40,9 @@ const form: any = reactive({
...
@@ -40,7 +40,9 @@ const form: any = reactive({
mobile
:
''
,
mobile
:
''
,
role
:
[],
role
:
[],
email
:
''
,
email
:
''
,
status
:
'1'
status
:
'1'
,
account_type
:
'1'
,
account_expired_time
:
''
,
})
})
const
rules
=
reactive
<
FormRules
>
({
const
rules
=
reactive
<
FormRules
>
({
...
@@ -50,11 +52,12 @@ const rules = reactive<FormRules>({
...
@@ -50,11 +52,12 @@ const rules = reactive<FormRules>({
gender
:
[{
required
:
true
,
message
:
'请选择性别'
,
trigger
:
'change'
}],
gender
:
[{
required
:
true
,
message
:
'请选择性别'
,
trigger
:
'change'
}],
mobile
:
[
mobile
:
[
{
required
:
true
,
message
:
'请输入手机号'
,
trigger
:
'blur'
},
{
required
:
true
,
message
:
'请输入手机号'
,
trigger
:
'blur'
},
{
pattern
:
/^1
(
3|4|5|6|7|8|9
)\d{9}
$/
,
message
:
'请输入正确的手机号'
,
trigger
:
'blur'
}
{
pattern
:
/^1
(
3|4|5|6|7|8|9
)\d{9}
$/
,
message
:
'请输入正确的手机号'
,
trigger
:
'blur'
}
,
],
],
role
:
[{
required
:
true
,
message
:
'请选择角色类型'
,
trigger
:
'change'
}],
role
:
[{
required
:
true
,
message
:
'请选择角色类型'
,
trigger
:
'change'
}],
email
:
[{
required
:
true
,
message
:
'请输入邮箱'
,
trigger
:
'blur'
}],
email
:
[{
required
:
true
,
message
:
'请输入邮箱'
,
trigger
:
'blur'
}],
status
:
[{
required
:
true
,
message
:
'请选择生效状态'
,
trigger
:
'change'
}]
status
:
[{
required
:
true
,
message
:
'请选择生效状态'
,
trigger
:
'change'
}],
account_type
:
[{
required
:
true
,
message
:
'请选择账号类型'
,
trigger
:
'change'
}],
})
})
if
(
userStore
.
roles
[
0
].
name
!==
'超级管理员'
)
{
if
(
userStore
.
roles
[
0
].
name
!==
'超级管理员'
)
{
form
.
organ_id
=
userStore
.
organization
?.
id
form
.
organ_id
=
userStore
.
organization
?.
id
...
@@ -67,11 +70,13 @@ const handleCancel = () => {
...
@@ -67,11 +70,13 @@ const handleCancel = () => {
// 确定
// 确定
const
handleConfirm
=
async
(
formEl
:
FormInstance
|
undefined
)
=>
{
const
handleConfirm
=
async
(
formEl
:
FormInstance
|
undefined
)
=>
{
if
(
!
formEl
)
return
if
(
!
formEl
)
return
await
formEl
.
validate
(
valid
=>
{
await
formEl
.
validate
(
(
valid
)
=>
{
if
(
valid
)
{
if
(
valid
)
{
if
(
props
.
isEdit
===
'0'
)
{
if
(
props
.
isEdit
===
'0'
)
{
form
.
role
=
form
.
role
.
toString
()
const
params
:
any
=
Object
.
assign
({},
form
,
{
const
params
:
any
=
Object
.
assign
({},
form
)
role
:
form
.
role
.
toString
(),
account_expired_time
:
form
.
account_expired_time
||
''
,
})
if
(
userStore
.
roles
[
0
].
name
===
'部门管理员'
)
{
if
(
userStore
.
roles
[
0
].
name
===
'部门管理员'
)
{
params
.
organ_id
=
userStore
.
organization
?.
id
params
.
organ_id
=
userStore
.
organization
?.
id
}
}
...
@@ -81,8 +86,10 @@ const handleConfirm = async (formEl: FormInstance | undefined) => {
...
@@ -81,8 +86,10 @@ const handleConfirm = async (formEl: FormInstance | undefined) => {
emit
(
'create'
)
emit
(
'create'
)
})
})
}
else
if
(
props
.
isEdit
===
'1'
)
{
}
else
if
(
props
.
isEdit
===
'1'
)
{
form
.
role
=
form
.
role
.
toString
()
const
params
:
any
=
Object
.
assign
({
id
:
props
.
id
},
form
,
{
const
params
:
any
=
Object
.
assign
({
id
:
props
.
id
},
form
)
role
:
form
.
role
.
toString
(),
account_expired_time
:
form
.
account_expired_time
||
''
,
})
updateStaff
(
params
).
then
(()
=>
{
updateStaff
(
params
).
then
(()
=>
{
ElMessage
.
success
(
'更新教工成功'
)
ElMessage
.
success
(
'更新教工成功'
)
emit
(
'update:isShowStaffDialog'
,
false
)
emit
(
'update:isShowStaffDialog'
,
false
)
...
@@ -99,7 +106,7 @@ const handleConfirm = async (formEl: FormInstance | undefined) => {
...
@@ -99,7 +106,7 @@ const handleConfirm = async (formEl: FormInstance | undefined) => {
if
(
props
.
isEdit
===
'2'
||
props
.
isEdit
===
'1'
)
{
if
(
props
.
isEdit
===
'2'
||
props
.
isEdit
===
'1'
)
{
const
params
:
any
=
{
id
:
props
.
id
}
const
params
:
any
=
{
id
:
props
.
id
}
getStaffDetail
(
params
).
then
((
res
:
any
)
=>
{
getStaffDetail
(
params
).
then
((
res
:
any
)
=>
{
Object
.
keys
(
form
).
forEach
(
key
=>
{
Object
.
keys
(
form
).
forEach
(
(
key
)
=>
{
form
[
key
]
=
res
.
data
[
key
]
form
[
key
]
=
res
.
data
[
key
]
})
})
form
.
role
=
res
.
data
.
role
.
split
(
','
)
form
.
role
=
res
.
data
.
role
.
split
(
','
)
...
@@ -116,14 +123,13 @@ if (props.isEdit === '2' || props.isEdit === '1') {
...
@@ -116,14 +123,13 @@ if (props.isEdit === '2' || props.isEdit === '1') {
:disabled=
"props.isEdit === '2' || props.isEdit === '1'"
:disabled=
"props.isEdit === '2' || props.isEdit === '1'"
placeholder=
"请选择所属部门/学校"
placeholder=
"请选择所属部门/学校"
style=
"width: 100%"
style=
"width: 100%"
v-if=
"userStore.roles[0].name === '超级管理员'"
v-if=
"userStore.roles[0].name === '超级管理员'"
>
>
<el-option
v-for=
"item in departmentList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
<el-option
v-for=
"item in departmentList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</el-select>
<el-input
:placeholder=
"userStore.organization?.name"
v-model=
"form.organ_id_name"
v-else
disabled
>
</el-input>
<el-input
:placeholder=
"userStore.organization?.name"
v-model=
"form.organ_id_name"
v-else
disabled
>
</el-input>
</el-form-item>
</el-form-item>
<el-form-item
label=
"姓名"
prop=
"name"
>
<el-form-item
label=
"姓名"
prop=
"name"
>
<el-input
v-model=
"form.name"
:disabled=
"props.isEdit === '2' || props.isEdit === '1'"
></el-input>
<el-input
v-model=
"form.name"
></el-input>
</el-form-item>
</el-form-item>
<el-form-item
label=
"性别"
prop=
"gender"
>
<el-form-item
label=
"性别"
prop=
"gender"
>
<el-radio-group
v-model=
"form.gender"
:disabled=
"props.isEdit === '2'"
>
<el-radio-group
v-model=
"form.gender"
:disabled=
"props.isEdit === '2'"
>
...
@@ -138,6 +144,20 @@ if (props.isEdit === '2' || props.isEdit === '1') {
...
@@ -138,6 +144,20 @@ if (props.isEdit === '2' || props.isEdit === '1') {
<el-checkbox
v-for=
"(item, index) in roleList"
:key=
"index"
:label=
"item.value"
>
{{
item
.
label
}}
</el-checkbox>
<el-checkbox
v-for=
"(item, index) in roleList"
:key=
"index"
:label=
"item.value"
>
{{
item
.
label
}}
</el-checkbox>
</el-checkbox-group>
</el-checkbox-group>
</el-form-item>
</el-form-item>
<el-form-item
label=
"账号类型"
prop=
"account_type"
>
<el-radio-group
v-model=
"form.account_type"
>
<el-radio
label=
"1"
>
正式
</el-radio>
<el-radio
label=
"2"
>
试用
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"有效期"
prop=
"account_expired_time"
>
<el-date-picker
v-model=
"form.account_expired_time"
type=
"datetime"
placeholder=
"请选择有效期"
style=
"width: 100%"
value-format=
"YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
<el-form-item
label=
"邮箱"
prop=
"email"
>
<el-form-item
label=
"邮箱"
prop=
"email"
>
<el-input
v-model=
"form.email"
:disabled=
"props.isEdit === '2'"
/>
<el-input
v-model=
"form.email"
:disabled=
"props.isEdit === '2'"
/>
</el-form-item>
</el-form-item>
...
...
src/modules/admin/staff/components/ImportStaff.vue
浏览文件 @
fb8b2339
...
@@ -105,6 +105,9 @@ const parseExcelData = (jsonData: any[]) => {
...
@@ -105,6 +105,9 @@ const parseExcelData = (jsonData: any[]) => {
role
:
''
,
role
:
''
,
role_name
:
row
[
'角色类型'
]
||
row
[
'role_name'
]
||
''
,
role_name
:
row
[
'角色类型'
]
||
row
[
'role_name'
]
||
''
,
email
:
row
[
'邮箱'
]
||
row
[
'email'
]
||
''
,
email
:
row
[
'邮箱'
]
||
row
[
'email'
]
||
''
,
account_type
:
''
,
account_type_name
:
row
[
'账号类型'
]
||
''
,
account_expired_time
:
row
[
'账号有效期'
]
||
row
[
'有效期'
]
||
''
,
status
:
'pending'
,
// 初始状态:待导入
status
:
'pending'
,
// 初始状态:待导入
errorMsg
:
''
,
// 错误信息
errorMsg
:
''
,
// 错误信息
}
}
...
@@ -128,6 +131,14 @@ const parseExcelData = (jsonData: any[]) => {
...
@@ -128,6 +131,14 @@ const parseExcelData = (jsonData: any[]) => {
item
.
gender
=
findValueByLabel
(
sexList
.
value
,
item
.
gender_name
)
item
.
gender
=
findValueByLabel
(
sexList
.
value
,
item
.
gender_name
)
}
}
// 账号类型映射
if
(
item
.
account_type_name
===
'试用'
)
{
item
.
account_type
=
'2'
}
else
{
item
.
account_type
=
'1'
item
.
account_type_name
=
'正式'
}
// 根据角色名称查找value(支持多个角色,用逗号分隔)
// 根据角色名称查找value(支持多个角色,用逗号分隔)
if
(
item
.
role_name
)
{
if
(
item
.
role_name
)
{
const
roleNames
=
item
.
role_name
.
split
(
','
).
map
((
r
:
string
)
=>
r
.
trim
())
const
roleNames
=
item
.
role_name
.
split
(
','
).
map
((
r
:
string
)
=>
r
.
trim
())
...
@@ -164,7 +175,7 @@ const handleBatchImport = async () => {
...
@@ -164,7 +175,7 @@ const handleBatchImport = async () => {
// 验证数据
// 验证数据
const
invalidData
=
tableData
.
value
.
filter
(
const
invalidData
=
tableData
.
value
.
filter
(
(
item
)
=>
!
item
.
name
||
!
item
.
organ_id
||
!
item
.
gender
||
!
item
.
mobile
||
!
item
.
role
||
!
item
.
email
(
item
)
=>
!
item
.
name
||
!
item
.
organ_id
||
!
item
.
gender
||
!
item
.
mobile
||
!
item
.
role
||
!
item
.
email
,
)
)
if
(
invalidData
.
length
>
0
)
{
if
(
invalidData
.
length
>
0
)
{
ElMessage
.
warning
(
'存在数据不完整,请检查'
)
ElMessage
.
warning
(
'存在数据不完整,请检查'
)
...
@@ -189,6 +200,8 @@ const handleBatchImport = async () => {
...
@@ -189,6 +200,8 @@ const handleBatchImport = async () => {
role
:
item
.
role
,
role
:
item
.
role
,
email
:
item
.
email
,
email
:
item
.
email
,
status
:
'1'
,
status
:
'1'
,
account_type
:
item
.
account_type
,
account_expired_time
:
item
.
account_expired_time
||
''
,
}
}
await
addStaff
(
params
)
await
addStaff
(
params
)
...
@@ -275,6 +288,8 @@ const getStatusType = (status: string) => {
...
@@ -275,6 +288,8 @@ const getStatusType = (status: string) => {
<el-table-column
prop=
"gender_name"
label=
"性别"
align=
"center"
/>
<el-table-column
prop=
"gender_name"
label=
"性别"
align=
"center"
/>
<el-table-column
prop=
"mobile"
label=
"手机号"
align=
"center"
/>
<el-table-column
prop=
"mobile"
label=
"手机号"
align=
"center"
/>
<el-table-column
prop=
"role_name"
label=
"角色类型"
align=
"center"
/>
<el-table-column
prop=
"role_name"
label=
"角色类型"
align=
"center"
/>
<el-table-column
prop=
"account_type_name"
label=
"账号类型"
align=
"center"
/>
<el-table-column
prop=
"account_expired_time"
label=
"账号有效期"
align=
"center"
width=
"180"
/>
<el-table-column
prop=
"email"
label=
"邮箱"
align=
"center"
/>
<el-table-column
prop=
"email"
label=
"邮箱"
align=
"center"
/>
<el-table-column
label=
"导入状态"
align=
"center"
width=
"120"
>
<el-table-column
label=
"导入状态"
align=
"center"
width=
"120"
>
<template
#
default=
"
{ row }">
<template
#
default=
"
{ row }">
...
...
src/modules/admin/staff/views/List.vue
浏览文件 @
fb8b2339
...
@@ -5,12 +5,14 @@ import ImportStaff from '../components/ImportStaff.vue'
...
@@ -5,12 +5,14 @@ import ImportStaff from '../components/ImportStaff.vue'
import
{
useProjectList
}
from
'@/composables/useGetProjectList'
import
{
useProjectList
}
from
'@/composables/useGetProjectList'
import
{
getStaffList
,
updateStaff
}
from
'../api'
import
{
getStaffList
,
updateStaff
}
from
'../api'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useMapStore
}
from
'@/stores/map'
// 判断当前用户是不是超级管理员
// 判断当前用户是不是超级管理员
const
user
=
useUserStore
().
roles
const
user
=
useUserStore
().
roles
const
isAdmin
=
!!
user
.
find
((
item
:
any
)
=>
item
.
name
===
'超级管理员'
)
const
isAdmin
=
!!
user
.
find
((
item
:
any
)
=>
item
.
name
===
'超级管理员'
)
const
departmentList
:
any
=
useProjectList
(
''
,
'79806610719731712'
).
departmentList
const
departmentList
:
any
=
useProjectList
(
''
,
'79806610719731712'
).
departmentList
const
statusList
=
useMapStore
().
getMapValuesByKey
(
'system_status'
)
const
appList
=
ref
()
const
appList
=
ref
()
const
studentId
=
ref
(
''
)
const
studentId
=
ref
(
''
)
...
@@ -25,11 +27,32 @@ const listOptions = $computed(() => {
...
@@ -25,11 +27,32 @@ const listOptions = $computed(() => {
params
:
{
params
:
{
name
:
''
,
name
:
''
,
organ_id
:
''
,
organ_id
:
''
,
account_type
:
''
,
status
:
''
,
},
},
},
},
filters
:
[
filters
:
[
{
type
:
'input'
,
prop
:
'name'
,
label
:
'姓名:'
,
placeholder
:
'姓名'
},
{
type
:
'input'
,
prop
:
'name'
,
label
:
'姓名:'
,
placeholder
:
'姓名'
},
{
type
:
'select'
,
prop
:
'organ_id'
,
slots
:
'filter-department'
},
{
type
:
'select'
,
prop
:
'organ_id'
,
slots
:
'filter-department'
},
{
type
:
'select'
,
prop
:
'account_type'
,
label
:
'账号类型:'
,
options
:
[
{
label
:
'正式'
,
id
:
'1'
},
{
label
:
'试用'
,
id
:
'2'
},
],
labelKey
:
'label'
,
valueKey
:
'id'
,
},
{
type
:
'select'
,
prop
:
'status'
,
label
:
'生效状态:'
,
options
:
statusList
,
labelKey
:
'label'
,
valueKey
:
'value'
,
},
],
],
columns
:
[
columns
:
[
{
label
:
'序号'
,
type
:
'index'
,
align
:
'center'
},
{
label
:
'序号'
,
type
:
'index'
,
align
:
'center'
},
...
@@ -39,6 +62,8 @@ const listOptions = $computed(() => {
...
@@ -39,6 +62,8 @@ const listOptions = $computed(() => {
{
label
:
'性别'
,
prop
:
'gender_name'
,
align
:
'center'
},
{
label
:
'性别'
,
prop
:
'gender_name'
,
align
:
'center'
},
{
label
:
'邮箱'
,
prop
:
'email'
,
align
:
'center'
,
width
:
200
},
{
label
:
'邮箱'
,
prop
:
'email'
,
align
:
'center'
,
width
:
200
},
{
label
:
'角色类型'
,
prop
:
'role_name'
,
align
:
'center'
},
{
label
:
'角色类型'
,
prop
:
'role_name'
,
align
:
'center'
},
{
label
:
'账号类型'
,
prop
:
'account_type_name'
,
align
:
'center'
},
{
label
:
'账号有效期'
,
prop
:
'account_expired_time'
,
align
:
'center'
,
width
:
200
},
{
label
:
'生效状态'
,
slots
:
'status'
,
align
:
'center'
},
{
label
:
'生效状态'
,
slots
:
'status'
,
align
:
'center'
},
{
label
:
'更新时间'
,
prop
:
'updated_time'
,
align
:
'center'
,
width
:
200
},
{
label
:
'更新时间'
,
prop
:
'updated_time'
,
align
:
'center'
,
width
:
200
},
{
label
:
'操作'
,
slots
:
'table-operate'
,
align
:
'center'
,
width
:
200
,
fixed
:
'right'
},
{
label
:
'操作'
,
slots
:
'table-operate'
,
align
:
'center'
,
width
:
200
,
fixed
:
'right'
},
...
...
src/modules/admin/student/api.ts
浏览文件 @
fb8b2339
import
httpRequest
from
'@/utils/axios'
import
httpRequest
from
'@/utils/axios'
// 获取学生列表
// 获取学生列表
export
function
getStudentList
(
params
?:
{
name
?:
string
;
organ_id
?:
string
;
page
?:
string
;
'per-page'
?:
string
})
{
export
function
getStudentList
(
params
?:
{
name
?:
string
organ_id
?:
string
mobile
?:
string
specialty_id
?:
string
class_id
?:
string
account_type
?:
string
status
?:
string
page
?:
string
'per-page'
?:
string
})
{
return
httpRequest
.
get
(
'/api/resource/v1/learning/student/list'
,
{
params
})
return
httpRequest
.
get
(
'/api/resource/v1/learning/student/list'
,
{
params
})
}
}
// 导入学生
// 导入学生
...
@@ -15,7 +25,15 @@ export function batchUpdateStudent(data: { url: string; name: string; size: numb
...
@@ -15,7 +25,15 @@ export function batchUpdateStudent(data: { url: string; name: string; size: numb
}
}
// 导出学生
// 导出学生
export
function
exportStudent
(
params
:
{
name
:
string
;
organ_id
:
string
})
{
export
function
exportStudent
(
params
:
{
name
:
string
organ_id
:
string
mobile
?:
string
specialty_id
?:
string
class_id
?:
string
account_type
?:
string
status
?:
string
})
{
return
httpRequest
.
get
(
'/api/resource/v1/learning/student/download'
,
{
params
,
responseType
:
'blob'
})
return
httpRequest
.
get
(
'/api/resource/v1/learning/student/download'
,
{
params
,
responseType
:
'blob'
})
}
}
...
@@ -30,6 +48,8 @@ export function addStudent(data?: {
...
@@ -30,6 +48,8 @@ export function addStudent(data?: {
sno_number
:
string
sno_number
:
string
class_id
?:
string
class_id
?:
string
specialty_id
?:
string
specialty_id
?:
string
account_type
?:
string
account_expired_time
?:
string
})
{
})
{
return
httpRequest
.
post
(
'/api/resource/v1/learning/student/create'
,
data
)
return
httpRequest
.
post
(
'/api/resource/v1/learning/student/create'
,
data
)
}
}
...
@@ -45,6 +65,8 @@ export function updateStudent(data?: {
...
@@ -45,6 +65,8 @@ export function updateStudent(data?: {
sno_number
:
string
sno_number
:
string
class_id
?:
string
class_id
?:
string
specialty_id
?:
string
specialty_id
?:
string
account_type
?:
string
account_expired_time
?:
string
})
{
})
{
return
httpRequest
.
post
(
'/api/resource/v1/learning/student/update'
,
data
)
return
httpRequest
.
post
(
'/api/resource/v1/learning/student/update'
,
data
)
}
}
...
...
src/modules/admin/student/components/AddStudent.vue
浏览文件 @
fb8b2339
...
@@ -27,7 +27,9 @@ const form: any = reactive({
...
@@ -27,7 +27,9 @@ const form: any = reactive({
organ_id
:
''
,
organ_id
:
''
,
specialty_id
:
''
,
specialty_id
:
''
,
class_id
:
''
,
class_id
:
''
,
status
:
'1'
status
:
'1'
,
account_type
:
'1'
,
account_expired_time
:
''
,
})
})
const
rules
=
reactive
<
FormRules
>
({
const
rules
=
reactive
<
FormRules
>
({
sno_number
:
[{
required
:
true
,
message
:
'请输入学号'
,
trigger
:
'blur'
}],
sno_number
:
[{
required
:
true
,
message
:
'请输入学号'
,
trigger
:
'blur'
}],
...
@@ -37,21 +39,22 @@ const rules = reactive<FormRules>({
...
@@ -37,21 +39,22 @@ const rules = reactive<FormRules>({
id_type
:
[{
required
:
true
,
message
:
'请选择证件类型'
,
trigger
:
'change'
}],
id_type
:
[{
required
:
true
,
message
:
'请选择证件类型'
,
trigger
:
'change'
}],
id_number
:
[{
required
:
true
,
message
:
'请输入证件号码'
,
trigger
:
'blur'
}],
id_number
:
[{
required
:
true
,
message
:
'请输入证件号码'
,
trigger
:
'blur'
}],
organ_id
:
[{
required
:
true
,
message
:
'请选择部门/学校'
,
trigger
:
'change'
}],
organ_id
:
[{
required
:
true
,
message
:
'请选择部门/学校'
,
trigger
:
'change'
}],
status
:
[{
required
:
true
,
message
:
'请选择状态'
,
trigger
:
'change'
}]
status
:
[{
required
:
true
,
message
:
'请选择状态'
,
trigger
:
'change'
}],
account_type
:
[{
required
:
true
,
message
:
'请选择账号类型'
,
trigger
:
'change'
}],
})
})
const
props
=
defineProps
({
const
props
=
defineProps
({
isShowAddDialog
:
{
isShowAddDialog
:
{
type
:
Boolean
type
:
Boolean
,
},
},
title
:
{
title
:
{
type
:
String
type
:
String
,
},
},
id
:
{
id
:
{
type
:
String
type
:
String
,
},
},
isEdit
:
{
isEdit
:
{
type
:
String
type
:
String
,
}
}
,
})
})
interface
Emits
{
interface
Emits
{
(
e
:
'update:isShowAddDialog'
,
isShowAddDialog
:
boolean
):
void
(
e
:
'update:isShowAddDialog'
,
isShowAddDialog
:
boolean
):
void
...
@@ -70,7 +73,7 @@ watch(
...
@@ -70,7 +73,7 @@ watch(
if
(
form
.
organ_id
!==
''
||
form
.
organ_id_name
!==
''
)
{
if
(
form
.
organ_id
!==
''
||
form
.
organ_id_name
!==
''
)
{
handleGetProList
()
handleGetProList
()
}
}
}
}
,
)
)
watch
(
watch
(
...
@@ -79,7 +82,7 @@ watch(
...
@@ -79,7 +82,7 @@ watch(
if
(
form
.
specialty_id
!==
''
)
{
if
(
form
.
specialty_id
!==
''
)
{
handleClassList
()
handleClassList
()
}
}
}
}
,
)
)
// 修改部门/学校为空的时候班级专业要清除数据
// 修改部门/学校为空的时候班级专业要清除数据
...
@@ -115,7 +118,7 @@ const handleClassList = () => {
...
@@ -115,7 +118,7 @@ const handleClassList = () => {
searchClass
({
searchClass
({
specialty_id
:
form
.
specialty_id
,
specialty_id
:
form
.
specialty_id
,
organ_id
:
form
.
organ_id
||
userStore
.
organization
?.
id
,
organ_id
:
form
.
organ_id
||
userStore
.
organization
?.
id
,
'per-page'
:
'100'
'per-page'
:
'100'
,
}).
then
((
res
:
any
)
=>
{
}).
then
((
res
:
any
)
=>
{
loading
.
value
=
false
loading
.
value
=
false
classList
.
value
=
res
.
data
.
list
.
filter
((
item
:
any
)
=>
item
.
status
===
'1'
)
classList
.
value
=
res
.
data
.
list
.
filter
((
item
:
any
)
=>
item
.
status
===
'1'
)
...
@@ -130,11 +133,13 @@ const handleClassList = () => {
...
@@ -130,11 +133,13 @@ const handleClassList = () => {
// 确认
// 确认
const
handleConfirm
=
async
(
formEl
:
FormInstance
|
undefined
)
=>
{
const
handleConfirm
=
async
(
formEl
:
FormInstance
|
undefined
)
=>
{
if
(
!
formEl
)
return
if
(
!
formEl
)
return
await
formEl
.
validate
(
valid
=>
{
await
formEl
.
validate
(
(
valid
)
=>
{
if
(
valid
)
{
if
(
valid
)
{
if
(
props
.
isEdit
===
'0'
)
{
if
(
props
.
isEdit
===
'0'
)
{
form
.
organ_id
=
form
.
organ_id
||
userStore
.
organization
?.
id
form
.
organ_id
=
form
.
organ_id
||
userStore
.
organization
?.
id
const
params
:
any
=
Object
.
assign
({},
form
)
const
params
:
any
=
Object
.
assign
({},
form
,
{
account_expired_time
:
form
.
account_expired_time
||
''
,
})
addStudent
(
params
).
then
(()
=>
{
addStudent
(
params
).
then
(()
=>
{
ElMessage
.
success
(
'新增学生成功'
)
ElMessage
.
success
(
'新增学生成功'
)
emit
(
'update:isShowAddDialog'
,
false
)
emit
(
'update:isShowAddDialog'
,
false
)
...
@@ -143,7 +148,9 @@ const handleConfirm = async (formEl: FormInstance | undefined) => {
...
@@ -143,7 +148,9 @@ const handleConfirm = async (formEl: FormInstance | undefined) => {
}
else
if
(
props
.
isEdit
===
'1'
)
{
}
else
if
(
props
.
isEdit
===
'1'
)
{
form
.
organ_id
=
form
.
organ_id
||
userStore
.
organization
?.
id
form
.
organ_id
=
form
.
organ_id
||
userStore
.
organization
?.
id
const
params
:
any
=
Object
.
assign
({
id
:
props
.
id
},
form
)
const
params
:
any
=
Object
.
assign
({
id
:
props
.
id
},
form
,
{
account_expired_time
:
form
.
account_expired_time
||
''
,
})
updateStudent
(
params
).
then
(()
=>
{
updateStudent
(
params
).
then
(()
=>
{
ElMessage
.
success
(
'更新学生成功'
)
ElMessage
.
success
(
'更新学生成功'
)
...
@@ -161,7 +168,7 @@ const handleConfirm = async (formEl: FormInstance | undefined) => {
...
@@ -161,7 +168,7 @@ const handleConfirm = async (formEl: FormInstance | undefined) => {
if
(
props
.
isEdit
===
'2'
||
props
.
isEdit
===
'1'
)
{
if
(
props
.
isEdit
===
'2'
||
props
.
isEdit
===
'1'
)
{
const
params
:
any
=
{
id
:
props
.
id
}
const
params
:
any
=
{
id
:
props
.
id
}
getStuDetail
(
params
).
then
((
res
:
any
)
=>
{
getStuDetail
(
params
).
then
((
res
:
any
)
=>
{
Object
.
keys
(
form
).
forEach
(
key
=>
{
Object
.
keys
(
form
).
forEach
(
(
key
)
=>
{
form
[
key
]
=
res
.
data
[
key
]
form
[
key
]
=
res
.
data
[
key
]
})
})
if
(
res
.
data
.
specialty_id
===
'0'
)
{
if
(
res
.
data
.
specialty_id
===
'0'
)
{
...
@@ -205,8 +212,7 @@ if (props.isEdit === '2' || props.isEdit === '1') {
...
@@ -205,8 +212,7 @@ if (props.isEdit === '2' || props.isEdit === '1') {
style=
"width: 100%"
style=
"width: 100%"
placeholder=
"请选择所属部门/学校"
placeholder=
"请选择所属部门/学校"
v-if=
"userStore.roles[0].name === '超级管理员'"
v-if=
"userStore.roles[0].name === '超级管理员'"
@
change=
"handleChangeOrgan"
@
change=
"handleChangeOrgan"
>
>
<el-option
v-for=
"item in departmentList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
<el-option
v-for=
"item in departmentList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</el-select>
<el-input
:placeholder=
"userStore.organization?.name"
v-model=
"form.organ_id_name"
v-else
disabled
>
</el-input>
<el-input
:placeholder=
"userStore.organization?.name"
v-model=
"form.organ_id_name"
v-else
disabled
>
</el-input>
...
@@ -219,8 +225,7 @@ if (props.isEdit === '2' || props.isEdit === '1') {
...
@@ -219,8 +225,7 @@ if (props.isEdit === '2' || props.isEdit === '1') {
placeholder=
"请选择专业"
placeholder=
"请选择专业"
style=
"width: 100%"
style=
"width: 100%"
@
change=
"handleChangeSpe"
@
change=
"handleChangeSpe"
:disabled=
"props.isEdit === '2'"
:disabled=
"props.isEdit === '2'"
>
>
<el-option
v-for=
"item in proList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
<el-option
v-for=
"item in proList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
...
@@ -231,11 +236,24 @@ if (props.isEdit === '2' || props.isEdit === '1') {
...
@@ -231,11 +236,24 @@ if (props.isEdit === '2' || props.isEdit === '1') {
clearable
clearable
placeholder=
"请选择班级"
placeholder=
"请选择班级"
style=
"width: 100%"
style=
"width: 100%"
:disabled=
"props.isEdit === '2'"
:disabled=
"props.isEdit === '2'"
>
>
<el-option
v-for=
"item in classList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
<el-option
v-for=
"item in classList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</el-select>
</el-form-item>
</el-form-item>
<el-form-item
label=
"账号类型"
prop=
"account_type"
>
<el-radio-group
v-model=
"form.account_type"
>
<el-radio
label=
"1"
>
正式
</el-radio>
<el-radio
label=
"2"
>
试用
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"有效期"
prop=
"account_expired_time"
>
<el-date-picker
v-model=
"form.account_expired_time"
type=
"datetime"
placeholder=
"请选择有效期"
style=
"width: 100%"
value-format=
"YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
<el-form-item
label=
"生效状态"
prop=
"status"
>
<el-form-item
label=
"生效状态"
prop=
"status"
>
<el-radio-group
v-model=
"form.status"
:disabled=
"props.isEdit === '2'"
>
<el-radio-group
v-model=
"form.status"
:disabled=
"props.isEdit === '2'"
>
<el-radio
v-for=
"(item, id) in statusList"
:key=
"id"
:label=
"item.value"
>
{{
item
.
label
}}
</el-radio>
<el-radio
v-for=
"(item, id) in statusList"
:key=
"id"
:label=
"item.value"
>
{{
item
.
label
}}
</el-radio>
...
...
src/modules/admin/student/components/ImportStudent.vue
浏览文件 @
fb8b2339
...
@@ -68,7 +68,7 @@ const fetchFileUpload = async (option: any) => {
...
@@ -68,7 +68,7 @@ const fetchFileUpload = async (option: any) => {
clearInterval
(
timer
)
clearInterval
(
timer
)
loading
.
value
=
false
loading
.
value
=
false
})
})
},
1000
)
},
1000
*
3
)
}
}
onUnmounted
(()
=>
{
onUnmounted
(()
=>
{
timer
&&
clearInterval
(
timer
)
timer
&&
clearInterval
(
timer
)
...
...
src/modules/admin/student/components/UpdateStudent.vue
浏览文件 @
fb8b2339
...
@@ -67,7 +67,7 @@ const fetchFileUpload = async (option: any) => {
...
@@ -67,7 +67,7 @@ const fetchFileUpload = async (option: any) => {
clearInterval
(
timer
)
clearInterval
(
timer
)
loading
.
value
=
false
loading
.
value
=
false
})
})
},
1000
)
},
1000
*
3
)
}
}
const
handleSubmitUpload
=
()
=>
{
const
handleSubmitUpload
=
()
=>
{
...
...
src/modules/admin/student/views/List.vue
浏览文件 @
fb8b2339
...
@@ -8,12 +8,14 @@ import UpdateStudent from '../components/UpdateStudent.vue'
...
@@ -8,12 +8,14 @@ import UpdateStudent from '../components/UpdateStudent.vue'
import
{
getStudentList
,
exportStudent
,
updateStudent
}
from
'../api'
import
{
getStudentList
,
exportStudent
,
updateStudent
}
from
'../api'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useUserStore
}
from
'@/stores/user'
import
{
useMapStore
}
from
'@/stores/map'
import
{
useClassList
,
useSpecialtyList
}
from
'../composables/useData'
import
{
useClassList
,
useSpecialtyList
}
from
'../composables/useData'
// 判断当前用户是不是超级管理员
// 判断当前用户是不是超级管理员
const
user
=
useUserStore
().
roles
const
user
=
useUserStore
().
roles
const
isAdmin
=
!!
user
.
find
((
item
:
any
)
=>
item
.
name
===
'超级管理员'
)
const
isAdmin
=
!!
user
.
find
((
item
:
any
)
=>
item
.
name
===
'超级管理员'
)
const
{
departmentList
}
=
useProjectList
(
''
,
'79806610719731712'
)
const
{
departmentList
}
=
useProjectList
(
''
,
'79806610719731712'
)
const
statusList
=
useMapStore
().
getMapValuesByKey
(
'system_status'
)
const
appList
=
ref
()
const
appList
=
ref
()
const
id
=
ref
(
''
)
const
id
=
ref
(
''
)
const
title
=
ref
(
''
)
const
title
=
ref
(
''
)
...
@@ -32,7 +34,15 @@ const listOptions = computed(() => {
...
@@ -32,7 +34,15 @@ const listOptions = computed(() => {
return
{
return
{
remote
:
{
remote
:
{
httpRequest
:
getStudentList
,
httpRequest
:
getStudentList
,
params
:
{
name
:
''
,
organ_id
:
''
,
mobile
:
''
,
specialty_id
:
''
,
class_id
:
''
},
params
:
{
name
:
''
,
organ_id
:
''
,
mobile
:
''
,
specialty_id
:
''
,
class_id
:
''
,
account_type
:
''
,
status
:
''
,
},
beforeRequest
:
(
requestPrams
:
any
)
=>
{
beforeRequest
:
(
requestPrams
:
any
)
=>
{
params
.
organ_id
=
requestPrams
.
organ_id
params
.
organ_id
=
requestPrams
.
organ_id
params
.
specialty_id
=
requestPrams
.
specialty_id
params
.
specialty_id
=
requestPrams
.
specialty_id
...
@@ -64,6 +74,25 @@ const listOptions = computed(() => {
...
@@ -64,6 +74,25 @@ const listOptions = computed(() => {
labelKey
:
'name'
,
labelKey
:
'name'
,
valueKey
:
'id'
,
valueKey
:
'id'
,
},
},
{
type
:
'select'
,
prop
:
'account_type'
,
label
:
'账号类型:'
,
options
:
[
{
label
:
'正式'
,
id
:
'1'
},
{
label
:
'试用'
,
id
:
'2'
},
],
labelKey
:
'label'
,
valueKey
:
'id'
,
},
{
type
:
'select'
,
prop
:
'status'
,
label
:
'生效状态:'
,
options
:
statusList
,
labelKey
:
'label'
,
valueKey
:
'value'
,
},
{
type
:
'input'
,
prop
:
'name'
,
label
:
'学生姓名:'
,
placeholder
:
'学生姓名'
},
{
type
:
'input'
,
prop
:
'name'
,
label
:
'学生姓名:'
,
placeholder
:
'学生姓名'
},
{
type
:
'input'
,
prop
:
'mobile'
,
label
:
'学生电话:'
,
placeholder
:
'学生电话'
},
{
type
:
'input'
,
prop
:
'mobile'
,
label
:
'学生电话:'
,
placeholder
:
'学生电话'
},
],
],
...
@@ -74,6 +103,8 @@ const listOptions = computed(() => {
...
@@ -74,6 +103,8 @@ const listOptions = computed(() => {
{
label
:
'姓名'
,
prop
:
'name'
,
align
:
'center'
,
minWidth
:
'100'
},
{
label
:
'姓名'
,
prop
:
'name'
,
align
:
'center'
,
minWidth
:
'100'
},
{
label
:
'性别'
,
prop
:
'gender_name'
,
align
:
'center'
},
{
label
:
'性别'
,
prop
:
'gender_name'
,
align
:
'center'
},
{
label
:
'联系电话'
,
prop
:
'mobile'
,
align
:
'center'
,
minWidth
:
'200'
},
{
label
:
'联系电话'
,
prop
:
'mobile'
,
align
:
'center'
,
minWidth
:
'200'
},
{
label
:
'账号类型'
,
prop
:
'account_type_name'
,
align
:
'center'
},
{
label
:
'账号有效期'
,
prop
:
'account_expired_time'
,
align
:
'center'
,
minWidth
:
'200'
},
{
label
:
'部门/学校'
,
prop
:
'organ_id_name'
,
align
:
'center'
,
minWidth
:
'200'
},
{
label
:
'部门/学校'
,
prop
:
'organ_id_name'
,
align
:
'center'
,
minWidth
:
'200'
},
{
label
:
'专业'
,
prop
:
'specialty_id_name'
,
align
:
'center'
,
minWidth
:
'200'
},
{
label
:
'专业'
,
prop
:
'specialty_id_name'
,
align
:
'center'
,
minWidth
:
'200'
},
{
label
:
'班级'
,
prop
:
'class_id_name'
,
align
:
'center'
,
minWidth
:
'200'
},
{
label
:
'班级'
,
prop
:
'class_id_name'
,
align
:
'center'
,
minWidth
:
'200'
},
...
@@ -156,7 +187,7 @@ const handleAnalysis = () => {
...
@@ -156,7 +187,7 @@ const handleAnalysis = () => {
// isShowAnalysisDialog.value = true
// isShowAnalysisDialog.value = true
window
.
open
(
window
.
open
(
import
.
meta
.
env
.
VITE_BI_URL
+
import
.
meta
.
env
.
VITE_BI_URL
+
'/bi/?proc=1&action=viewer&hback=true&isInPreview=true&db=!7d2b!!8346!!6559!!80b2!e-SaaS!2f!!751f!!6e90!!5730!!5206!!5e03!.db&platform=PC&browserType=chrome'
'/bi/?proc=1&action=viewer&hback=true&isInPreview=true&db=!7d2b!!8346!!6559!!80b2!e-SaaS!2f!!751f!!6e90!!5730!!5206!!5e03!.db&platform=PC&browserType=chrome'
,
)
)
}
}
</
script
>
</
script
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论