Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nanMoMentorPlatform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
node_server
nanMoMentorPlatform
Commits
b50b20c3
Commit
b50b20c3
authored
Jun 24, 2026
by
PC-20251223ZVQQ\Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
管理端-测评题库
parent
4544d0b0
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
332 additions
and
0 deletions
+332
-0
teacherSurvey.ts
src/biz/admin/teacherSurvey.ts
+226
-0
admin.ts
src/routers/admin.ts
+106
-0
No files found.
src/biz/admin/teacherSurvey.ts
0 → 100644
View file @
b50b20c3
/**测评管理 */
import
{
selectDataListByParam
,
selectOneDataByParam
}
from
"../../data/findData"
;
import
{
updateManyData
}
from
"../../data/updateData"
;
import
{
addData
}
from
"../../data/addData"
;
import
{
delData
}
from
"../../data/delData"
;
import
{
TABLENAME
,
TABLEID
}
from
"../../config/dbEnum"
;
import
{
BizError
}
from
"../../util/bizError"
;
import
{
ERRORENUM
}
from
"../../config/errorEnum"
;
import
{
getCurrentSemester
}
from
"../common/semesterService"
;
import
{
mysqlModelMap
}
from
"../../model/sqlModelBind"
;
import
{
Op
,
Sequelize
}
from
"sequelize"
;
import
{
hasData
}
from
"../../tools/system"
;
/**CASE WHEN 状态计算表达式 */
const
STATUS_CASE_SQL
=
`CASE WHEN start_time IS NOT NULL AND NOW() < start_time THEN 0 WHEN end_time IS NOT NULL AND NOW() > end_time THEN 2 ELSE 1 END`
;
/**
* 测评题库列表
* @param param.surveyName 测评标题(可选,模糊搜索)
* @param param.status 状态(可选,0=未开始 1=进行中 2=已结束)
* @param param.page 页码
* @param param.pageSize 每页大小
*/
export
async
function
getSurveyList
(
param
:
{
surveyName
?:
string
;
status
?:
number
;
page
:
number
;
pageSize
:
number
})
{
let
{
surveyName
,
status
,
page
,
pageSize
}
=
param
;
let
tableModel
=
mysqlModelMap
[
TABLENAME
.
测评活动表
];
// 构建 WHERE 条件
let
where
:
any
=
{};
if
(
surveyName
)
{
where
.
name
=
{
[
Op
.
like
]:
`%
${
surveyName
}
%`
};
}
// 构建 attributes(含 CASE WHEN 计算列)
let
attributes
:
any
[]
=
[
'id'
,
'name'
,
'start_time'
,
'end_time'
,
'is_open'
,
'description'
,
'semester_id'
,
[
Sequelize
.
literal
(
STATUS_CASE_SQL
),
'status'
]
];
// 构建查询参数(不含 having)
let
selectParam
:
any
=
{
where
,
attributes
,
limit
:
pageSize
||
10
,
offset
:
((
page
||
1
)
-
1
)
*
(
pageSize
||
10
),
order
:
[[
Sequelize
.
col
(
'id'
),
'DESC'
]]
};
// 如果传了 status,需要在 WHERE 中用子查询方式过滤,避免 HAVING 与 count 冲突
if
(
status
!==
undefined
&&
status
!==
null
)
{
// 将 status 条件拼入 WHERE,直接用 CASE WHEN 表达式判断
where
[
Op
.
and
]
=
Sequelize
.
literal
(
`
${
STATUS_CASE_SQL
}
=
${
status
}
`
);
selectParam
.
where
=
where
;
}
const
result
=
await
tableModel
.
findAndCountAll
(
selectParam
);
let
dataList
=
result
.
rows
.
map
((
row
:
any
)
=>
row
.
toJSON
());
return
{
count
:
result
.
count
,
dataList
:
dataList
};
}
/**
* 新增测评题库
* @param param.surveyName 题库标题
* @param param.startTime 开始时间
* @param param.endTime 结束时间
* @param param.isOpen 是否开放(0否1是)
* @param param.description 题库说明
* @param param.questions 题目列表
* @param param.created_by 创建人
*/
export
async
function
createSurvey
(
param
:
{
surveyName
:
string
;
startTime
:
string
;
endTime
?:
string
;
isOpen
:
number
;
description
?:
string
;
questions
:
any
[];
created_by
:
string
;
})
{
let
{
surveyName
,
startTime
,
endTime
,
isOpen
,
description
,
questions
,
created_by
}
=
param
;
/**获取当前学期 */
let
semester
=
await
getCurrentSemester
();
/**插入 survey 表 */
let
surveyData
:
any
=
{
name
:
surveyName
,
semester_id
:
semester
.
id
,
start_time
:
startTime
||
null
,
end_time
:
endTime
||
null
,
is_open
:
isOpen
?
true
:
false
,
description
:
description
||
null
};
await
addData
(
TABLENAME
.
测评活动表
,
surveyData
);
/**查回自增ID */
let
newSurvey
=
await
selectOneDataByParam
(
TABLENAME
.
测评活动表
,
{
name
:
surveyName
,
semester_id
:
semester
.
id
,
"%orderDesc%"
:
"id"
,
"%limit%"
:
1
});
let
surveyId
=
(
newSurvey
.
data
as
any
).
id
;
/**逐条插入题目 */
for
(
let
i
=
0
;
i
<
questions
.
length
;
i
++
)
{
let
q
=
questions
[
i
];
await
addData
(
TABLENAME
.
测评题目表
,
{
survey_id
:
surveyId
,
question_code
:
q
.
question_code
,
question_type
:
q
.
question_type
,
question_text
:
q
.
question_text
,
options
:
q
.
options
||
null
,
is_required
:
q
.
is_required
!==
undefined
?
(
q
.
is_required
?
true
:
false
)
:
true
,
sort_order
:
i
});
}
return
{
isSuccess
:
true
};
}
/**
* 修改测评题库
* @param param.surveyId 测评ID
* @param param.surveyName 题库标题
* @param param.startTime 开始时间
* @param param.endTime 结束时间
* @param param.isOpen 是否开放
* @param param.description 题库说明
* @param param.questions 题目列表
* @param param.update_by 修改人
*/
export
async
function
updateSurvey
(
param
:
{
surveyId
:
number
;
surveyName
:
string
;
startTime
:
string
;
endTime
?:
string
;
isOpen
:
number
;
description
?:
string
;
questions
:
any
[];
update_by
:
string
;
})
{
let
{
surveyId
,
surveyName
,
startTime
,
endTime
,
isOpen
,
description
,
questions
,
update_by
}
=
param
;
/**校验测评是否存在 */
let
survey
=
await
selectOneDataByParam
(
TABLENAME
.
测评活动表
,
{
id
:
surveyId
});
if
(
!
hasData
(
survey
))
{
throw
new
BizError
(
ERRORENUM
.
未找到数据
,
'测评不存在'
);
}
/**更新 survey 表 */
await
updateManyData
(
TABLENAME
.
测评活动表
,
{
id
:
surveyId
},
{
name
:
surveyName
,
start_time
:
startTime
||
null
,
end_time
:
endTime
||
null
,
is_open
:
isOpen
?
true
:
false
,
description
:
description
||
null
});
/**操作 survey_question 表:先删后加 */
await
delData
(
TABLENAME
.
测评题目表
,
{
survey_id
:
surveyId
});
for
(
let
i
=
0
;
i
<
questions
.
length
;
i
++
)
{
let
q
=
questions
[
i
];
await
addData
(
TABLENAME
.
测评题目表
,
{
survey_id
:
surveyId
,
question_code
:
q
.
question_code
,
question_type
:
q
.
question_type
,
question_text
:
q
.
question_text
,
options
:
q
.
options
||
null
,
is_required
:
q
.
is_required
!==
undefined
?
(
q
.
is_required
?
true
:
false
)
:
true
,
sort_order
:
i
});
}
return
{
isSuccess
:
true
};
}
/**
* 测评详情
* @param surveyId 测评ID
*/
export
async
function
surveyInfo
(
surveyId
:
number
)
{
/**查测评活动 */
let
survey
=
await
selectOneDataByParam
(
TABLENAME
.
测评活动表
,
{
id
:
surveyId
});
if
(
!
hasData
(
survey
))
{
throw
new
BizError
(
ERRORENUM
.
未找到数据
,
'测评不存在'
);
}
let
surveyData
=
survey
.
data
as
any
;
/**查题目列表(按排序号升序) */
let
questions
=
await
selectDataListByParam
(
TABLENAME
.
测评题目表
,
{
survey_id
:
surveyId
,
"%orderAsc%"
:
"sort_order"
});
let
questionList
=
(
questions
.
data
||
[]).
map
((
q
:
any
)
=>
({
question_code
:
q
.
question_code
,
question_type
:
q
.
question_type
,
question_text
:
q
.
question_text
,
options
:
q
.
options
,
is_required
:
q
.
is_required
?
1
:
0
,
sort_order
:
q
.
sort_order
}));
return
{
id
:
surveyData
.
id
,
name
:
surveyData
.
name
,
start_time
:
surveyData
.
start_time
,
end_time
:
surveyData
.
end_time
,
is_open
:
surveyData
.
is_open
?
1
:
0
,
description
:
surveyData
.
description
,
questions
:
questionList
};
}
src/routers/admin.ts
View file @
b50b20c3
...
...
@@ -4,6 +4,7 @@
*/
import
asyncHandler
from
'express-async-handler'
;
import
*
as
teacherSurveyBiz
from
'../biz/admin/teacherSurvey'
;
import
*
as
teacherManagerBiz
from
'../biz/admin/teacherManager'
;
import
*
as
studentManagerBiz
from
'../biz/admin/studentManager'
;
import
*
as
matchManagerBiz
from
'../biz/admin/matchManager'
;
...
...
@@ -239,6 +240,14 @@ export function setRouter(httpServer) {
/** 添加设置管理员 */
httpServer
.
post
(
'/api/admin/user/set/admin'
,
checkUser
,
checkRole
(
USERROLE
.
管理员
),
asyncHandler
(
setAdmin
));
httpServer
.
post
(
'/api/admin/user/remove/admin'
,
checkUser
,
checkRole
(
USERROLE
.
管理员
),
asyncHandler
(
removeAdmin
));
// ======================================= 测评题库 =======================================
/** 测评题库 - teacherSurvey.ts */
httpServer
.
post
(
'/api/admin/survey/list'
,
checkUser
,
checkRole
(
USERROLE
.
管理员
),
asyncHandler
(
getSurveyList
));
httpServer
.
post
(
'/api/admin/survey/add'
,
checkUser
,
checkRole
(
USERROLE
.
管理员
),
asyncHandler
(
createSurvey
));
httpServer
.
post
(
'/api/admin/survey/edit'
,
checkUser
,
checkRole
(
USERROLE
.
管理员
),
asyncHandler
(
updateSurvey
));
httpServer
.
post
(
'/api/admin/survey/info'
,
checkUser
,
checkRole
(
USERROLE
.
管理员
),
asyncHandler
(
surveyInfo
));
}
// ==================== 导师管理 ====================
...
...
@@ -1534,12 +1543,109 @@ async function removeAdmin(req, res) {
res
.
success
(
result
);
}
// ==================== 测评题库 ====================
/**
* 测评题库列表
* @param req
* @param res
*/
async
function
getSurveyList
(
req
,
res
)
{
let
reqConf
=
{
surveyName
:
'String'
,
status
:
'Number'
,
page
:
'Number'
,
pageSize
:
'Number'
};
const
NotMustHaveKeys
=
[
'surveyName'
,
'status'
,
'pageSize'
];
let
{
surveyName
,
status
,
page
,
pageSize
}
=
eccReqParamater
(
reqConf
,
req
.
body
,
NotMustHaveKeys
);
let
params
=
{
surveyName
,
status
,
page
:
page
||
1
,
pageSize
:
pageSize
||
10
};
let
result
=
await
teacherSurveyBiz
.
getSurveyList
(
params
);
res
.
success
(
result
);
}
/**
* 新增测评题库
* @param req
* surveyName 题库标题
* startTime 开始时间
* endTime 结束时间
* isOpen 是否开放,如否0是1
* description 题库说明
* questions 题目选项([{"question_code":"Q1","question_type":"multiple_choice","question_text":"导师迟到次数","options":[{"key":"A","value":"0次"},{"key":"B","value":"1-3次"}
* ,{"key":"C","value":"3次以上"}],"is_required":1},{"question_code":"Q2","question_type":"text","question_text":"您对本次测评有何评价","is_required":0}])
* question_code 题目编号,如Q1、Q2
* question_type 题目类型,如单选single_choice、多选multiple_choice、文本text
* question_text 题目内容
* options 选项列表,JSON格式:[{"key":"A","value":"0次"},{"key":"B","value":"1-2次"}]
* is_required 是否必填,如否0是1,默认为1
* @param res
*/
async
function
createSurvey
(
req
,
res
)
{
const
userInfo
=
req
.
userInfo
;
let
reqConf
=
{
surveyName
:
'String'
,
startTime
:
'String'
,
endTime
:
'String'
,
isOpen
:
'Number'
,
description
:
'String'
,
questions
:
'Array'
};
const
NotMustHaveKeys
=
[
'endTime'
,
'description'
];
let
{
surveyName
,
startTime
,
endTime
,
isOpen
,
description
,
questions
}
=
eccReqParamater
(
reqConf
,
req
.
body
,
NotMustHaveKeys
);
let
parentData
=
{
surveyName
,
startTime
,
endTime
,
isOpen
,
description
,
questions
,
created_by
:
userInfo
.
userId
};
let
result
=
await
teacherSurveyBiz
.
createSurvey
(
parentData
);
res
.
success
(
result
);
}
/**
* 修改测评题库
* @param req
* surveyId 测评id
* @param res
*/
async
function
updateSurvey
(
req
,
res
)
{
const
userInfo
=
req
.
userInfo
;
let
reqConf
=
{
surveyId
:
'Number'
,
surveyName
:
'String'
,
startTime
:
'String'
,
endTime
:
'String'
,
isOpen
:
'Number'
,
description
:
'String'
,
questions
:
'Array'
};
const
NotMustHaveKeys
=
[
'endTime'
,
'description'
];
let
{
surveyId
,
surveyName
,
startTime
,
endTime
,
isOpen
,
description
,
questions
}
=
eccReqParamater
(
reqConf
,
req
.
body
,
NotMustHaveKeys
);
let
parentData
=
{
surveyId
,
surveyName
,
startTime
,
endTime
,
isOpen
,
description
,
questions
,
update_by
:
userInfo
.
userId
};
let
result
=
await
teacherSurveyBiz
.
updateSurvey
(
parentData
);
res
.
success
(
result
);
}
/**
* 测评详情
* @param req
* @param res
*/
async
function
surveyInfo
(
req
,
res
)
{
let
reqConf
=
{
surveyId
:
'Number'
};
const
NotMustHaveKeys
=
[];
let
{
surveyId
}
=
eccReqParamater
(
reqConf
,
req
.
body
,
NotMustHaveKeys
);
let
result
=
await
teacherSurveyBiz
.
surveyInfo
(
surveyId
);
res
.
success
(
result
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment