Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
publicIntelligence
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
publicIntelligence
Commits
654a48d6
Commit
654a48d6
authored
May 18, 2026
by
chenjinjing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
no message
parent
d920324d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
504 additions
and
3 deletions
+504
-3
serverConfig.xml
serverConfig.xml
+1
-1
throwMethod.ts
src/biz/throwMethod.ts
+393
-0
main.ts
src/main.ts
+2
-1
router.ts
src/routers/router.ts
+2
-0
throwMethod.ts
src/routers/throwMethod.ts
+101
-0
tsconfig.json
tsconfig.json
+5
-1
No files found.
serverConfig.xml
View file @
654a48d6
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
<dbServer>
http://127.0.0.1:13276
</dbServer>
<dbServer>
http://127.0.0.1:13276
</dbServer>
<mysqldb>
<mysqldb>
<!-- 本地mysql配置 -->
<!-- 本地mysql配置 -->
<mysqlHost>
localhost
</mysqlHost>
<mysqlHost>
127.0.0.1
</mysqlHost>
<mysqlPort>
3306
</mysqlPort>
<mysqlPort>
3306
</mysqlPort>
<mysqlUser>
root
</mysqlUser>
<mysqlUser>
root
</mysqlUser>
<mysqlPwd>
123456
</mysqlPwd>
<mysqlPwd>
123456
</mysqlPwd>
...
...
src/biz/throwMethod.ts
0 → 100644
View file @
654a48d6
import
{
TABLENAME
}
from
"../config/dbEnum"
;
import
{
STATE
}
from
"../config/enum"
;
import
{
ERRORENUM
}
from
"../config/errorEnum"
;
import
{
selectDataListByParam
,
selectDataWithCustomOrder
}
from
"../data/findData"
;
import
{
BizError
}
from
"../util/bizError"
;
// ==================== 辅助函数:安全取值 ====================
function
getFieldValue
(
item
:
any
,
field
:
string
):
any
{
if
(
!
item
)
return
undefined
;
// Sequelize 实例
if
(
item
.
dataValues
&&
item
.
dataValues
[
field
]
!==
undefined
)
{
return
item
.
dataValues
[
field
];
}
// 普通对象
return
item
[
field
];
}
// ==================== 核心业务函数 ====================
export
async
function
getStudentAbilityScoresWithComparison
(
student_id
:
string
)
{
if
(
!
student_id
)
{
throw
new
BizError
(
ERRORENUM
.
参数错误
,
'学生ID不能为空'
);
}
// 获取已完成记录,按时间倒序
const
allRecords
=
await
selectDataWithCustomOrder
(
TABLENAME
.
答题记录表
,
{
student_id
,
answer_status
:
STATE
.
是
},
[
"record_id"
,
"student_id"
,
"student_name"
,
"total_score"
,
"answer_time"
,
"answer_status"
],
[[
"answer_time"
,
"DESC"
]]
);
if
(
!
allRecords
.
data
||
allRecords
.
data
.
length
===
0
)
{
return
getEmptyResult
(
student_id
);
}
const
currentRecord
=
allRecords
.
data
[
0
];
const
previousRecord
=
allRecords
.
data
.
length
>=
2
?
allRecords
.
data
[
1
]
:
null
;
const
currentScores
=
await
calculateDimensionScoresByRecord
(
getFieldValue
(
currentRecord
,
'record_id'
));
let
previousScores
=
null
;
if
(
previousRecord
)
{
previousScores
=
await
calculateDimensionScoresByRecord
(
getFieldValue
(
previousRecord
,
'record_id'
));
}
return
await
buildAbilityResult
(
student_id
,
currentRecord
,
currentScores
,
previousRecord
,
previousScores
);
}
/**
* 根据答题记录ID计算各维度得分
* 修正:使用 %in% 操作符 + 安全取值
*/
async
function
calculateDimensionScoresByRecord
(
record_id
:
string
)
{
// 1. 获取答题明细
const
answerDetails
=
await
selectDataListByParam
(
TABLENAME
.
答题记录明细表
,
{
record_id
},
[
"detail_id"
,
"score"
,
"question_id"
]
);
if
(
!
answerDetails
.
data
||
answerDetails
.
data
.
length
===
0
)
{
return
{};
}
// 2. 收集所有 question_id(去重)
const
questionIds
=
[...
new
Set
(
answerDetails
.
data
.
map
(
d
=>
getFieldValue
(
d
,
'question_id'
)))];
// 3. 批量查询题目(使用 %in%)
const
questions
=
await
selectDataListByParam
(
TABLENAME
.
题目表
,
{
question_id
:
{
"%in%"
:
questionIds
}
},
[
"question_id"
,
"dimension_id"
]
);
const
questionDimensionMap
=
new
Map
();
questions
.
data
.
forEach
((
q
:
any
)
=>
{
const
qid
=
getFieldValue
(
q
,
'question_id'
);
const
did
=
getFieldValue
(
q
,
'dimension_id'
);
if
(
qid
&&
did
)
questionDimensionMap
.
set
(
qid
,
did
);
});
// 4. 收集 dimension_id 并查询维度名称
const
dimensionIds
=
[...
new
Set
(
questions
.
data
.
map
(
q
=>
getFieldValue
(
q
,
'dimension_id'
)))];
const
dimensions
=
await
selectDataListByParam
(
TABLENAME
.
维度表
,
{
dimension_id
:
{
"%in%"
:
dimensionIds
}
},
[
"dimension_id"
,
"dimension_name"
]
);
const
dimensionNameMap
=
new
Map
();
dimensions
.
data
.
forEach
((
dim
:
any
)
=>
{
const
did
=
getFieldValue
(
dim
,
'dimension_id'
);
const
dname
=
getFieldValue
(
dim
,
'dimension_name'
);
if
(
did
&&
dname
)
dimensionNameMap
.
set
(
did
,
dname
);
});
// 5. 初始化得分对象
const
dimensionScores
:
{
[
key
:
string
]:
number
}
=
{};
dimensions
.
data
.
forEach
((
dim
:
any
)
=>
{
const
dname
=
getFieldValue
(
dim
,
'dimension_name'
);
if
(
dname
)
dimensionScores
[
dname
]
=
0
;
});
// 6. 累加得分
answerDetails
.
data
.
forEach
((
detail
:
any
)
=>
{
const
qid
=
getFieldValue
(
detail
,
'question_id'
);
const
score
=
Number
(
getFieldValue
(
detail
,
'score'
))
||
0
;
const
did
=
questionDimensionMap
.
get
(
qid
);
if
(
did
)
{
const
dname
=
dimensionNameMap
.
get
(
did
);
if
(
dname
&&
dimensionScores
.
hasOwnProperty
(
dname
))
{
dimensionScores
[
dname
]
+=
score
;
}
}
});
return
dimensionScores
;
}
// 根据维度得分计算三大方向得分
function
calculateDirectionScoresFromDimensions
(
dimensionScores
:
{
[
key
:
string
]:
number
})
{
return
{
gong
:
(
dimensionScores
[
'家国情怀'
]
||
0
)
+
(
dimensionScores
[
'国际视野'
]
||
0
)
+
(
dimensionScores
[
'责任担当'
]
||
0
),
zhi
:
(
dimensionScores
[
'学业扎实'
]
||
0
)
+
(
dimensionScores
[
'勇于创新'
]
||
0
)
+
(
dimensionScores
[
'善于学习'
]
||
0
),
neng
:
(
dimensionScores
[
'健康生活'
]
||
0
)
+
(
dimensionScores
[
'审美情趣'
]
||
0
)
+
(
dimensionScores
[
'劳动意识'
]
||
0
)
};
}
// 分数描述
function
getScoreDescription
(
score
:
number
):
string
{
if
(
score
>=
85
)
return
'优秀'
;
if
(
score
>=
70
)
return
'良好'
;
if
(
score
>=
60
)
return
'合格'
;
return
'待提升'
;
}
// 默认狮子形象
function
getDefaultLionImage
()
{
return
{
standardName
:
''
,
aliasName
:
''
,
characteristic
:
''
,
magicArtifact
:
''
,
magicArtifactText
:
''
,
suggestion
:
''
,
suggestionText
:
''
,
lionImage
:
''
};
}
// 根据方向得分匹配狮子形象(复用 question.ts 逻辑)
async
function
getLionImageByScores
(
scores
:
{
公
:
number
;
智
:
number
;
能
:
number
})
{
const
{
公
:
publicScore
,
智
:
intelligenceScore
,
能
:
abilityScore
}
=
scores
;
const
allLionImages
=
await
selectDataListByParam
(
TABLENAME
.
狮子形象表
,
{},
[
'lion_id'
,
'standard_name'
,
'alias_name'
,
'characteristic'
,
'judgment_condition'
,
'magic_artifact'
,
'magic_artifact_text'
,
'suggestion'
,
'suggestion_text'
,
'lion_image'
]
);
if
(
!
allLionImages
.
data
||
allLionImages
.
data
.
length
===
0
)
{
return
getDefaultLionImage
();
}
for
(
const
lion
of
allLionImages
.
data
)
{
const
condition
=
lion
.
judgment_condition
;
if
(
condition
&&
evaluateCondition
(
condition
,
publicScore
,
intelligenceScore
,
abilityScore
))
{
return
{
standardName
:
lion
.
standard_name
,
aliasName
:
lion
.
alias_name
,
characteristic
:
lion
.
characteristic
,
magicArtifact
:
lion
.
magic_artifact
,
magicArtifactText
:
lion
.
magic_artifact_text
,
suggestion
:
lion
.
suggestion
,
suggestionText
:
lion
.
suggestion_text
,
lionImage
:
lion
.
lion_image
};
}
}
return
getDefaultLionImage
();
}
function
evaluateCondition
(
condition
:
string
,
publicScore
:
number
,
intelligenceScore
:
number
,
abilityScore
:
number
):
boolean
{
const
parts
=
condition
.
split
(
'&'
).
map
(
c
=>
c
.
trim
());
for
(
const
part
of
parts
)
{
if
(
!
evaluateSingleCondition
(
part
,
publicScore
,
intelligenceScore
,
abilityScore
))
{
return
false
;
}
}
return
true
;
}
function
evaluateSingleCondition
(
cond
:
string
,
publicScore
:
number
,
intelligenceScore
:
number
,
abilityScore
:
number
):
boolean
{
const
match
=
cond
.
match
(
/
(
公|智|能
)([
<>≥≤≈=
]
+
)(\d
+
)
/
);
if
(
!
match
)
return
false
;
const
direction
=
match
[
1
];
const
operator
=
match
[
2
];
const
value
=
parseInt
(
match
[
3
]);
let
score
:
number
;
switch
(
direction
)
{
case
'公'
:
score
=
publicScore
;
break
;
case
'智'
:
score
=
intelligenceScore
;
break
;
case
'能'
:
score
=
abilityScore
;
break
;
default
:
return
false
;
}
switch
(
operator
)
{
case
'>'
:
return
score
>
value
;
case
'<'
:
return
score
<
value
;
case
'≥'
:
return
score
>=
value
;
case
'>='
:
return
score
>=
value
;
case
'≤'
:
return
score
<=
value
;
case
'<='
:
return
score
<=
value
;
case
'≈'
:
return
Math
.
abs
(
score
-
value
)
<=
5
;
case
'='
:
return
score
===
value
;
default
:
return
false
;
}
}
// 构建最终返回结果
async
function
buildAbilityResult
(
student_id
:
string
,
currentRecord
:
any
,
currentScores
:
{
[
key
:
string
]:
number
},
previousRecord
:
any
,
previousScores
:
{
[
key
:
string
]:
number
}
|
null
)
{
const
abilitiesKeys
=
[
'jgqh'
,
'gjsy'
,
'zrdd'
,
'xyzs'
,
'yycx'
,
'syxx'
,
'jksh'
,
'smqq'
,
'ldys'
];
const
abilitiesNames
:
Record
<
string
,
string
>
=
{
jgqh
:
'家国情怀'
,
gjsy
:
'国际视野'
,
zrdd
:
'责任担当'
,
xyzs
:
'学业扎实'
,
yycx
:
'勇于创新'
,
syxx
:
'善于学习'
,
jksh
:
'健康生活'
,
smqq
:
'审美情趣'
,
ldys
:
'劳动意识'
};
const
abilities
:
any
=
{};
for
(
const
key
of
abilitiesKeys
)
{
const
current
=
currentScores
[
abilitiesNames
[
key
]]
||
0
;
const
previous
=
previousScores
?
(
previousScores
[
abilitiesNames
[
key
]]
||
0
)
:
null
;
abilities
[
key
]
=
{
name
:
abilitiesNames
[
key
],
currentScore
:
current
,
previousScore
:
previous
,
yoyChange
:
previous
!==
null
?
current
-
previous
:
null
,
yoyPercent
:
(
previous
!==
null
&&
previous
!==
0
)
?
parseFloat
(((
current
-
previous
)
/
previous
*
100
).
toFixed
(
2
))
:
null
};
}
const
currentDir
=
calculateDirectionScoresFromDimensions
(
currentScores
);
const
previousDir
=
previousScores
?
calculateDirectionScoresFromDimensions
(
previousScores
)
:
null
;
const
directionScores
=
{
gong
:
{
name
:
'公'
,
currentScore
:
currentDir
.
gong
,
previousScore
:
previousDir
?.
gong
||
null
,
yoyChange
:
previousDir
?
currentDir
.
gong
-
previousDir
.
gong
:
null
,
yoyPercent
:
(
previousDir
&&
previousDir
.
gong
!==
0
)
?
parseFloat
(((
currentDir
.
gong
-
previousDir
.
gong
)
/
previousDir
.
gong
*
100
).
toFixed
(
2
))
:
null
},
zhi
:
{
name
:
'智'
,
currentScore
:
currentDir
.
zhi
,
previousScore
:
previousDir
?.
zhi
||
null
,
yoyChange
:
previousDir
?
currentDir
.
zhi
-
previousDir
.
zhi
:
null
,
yoyPercent
:
(
previousDir
&&
previousDir
.
zhi
!==
0
)
?
parseFloat
(((
currentDir
.
zhi
-
previousDir
.
zhi
)
/
previousDir
.
zhi
*
100
).
toFixed
(
2
))
:
null
},
neng
:
{
name
:
'能'
,
currentScore
:
currentDir
.
neng
,
previousScore
:
previousDir
?.
neng
||
null
,
yoyChange
:
previousDir
?
currentDir
.
neng
-
previousDir
.
neng
:
null
,
yoyPercent
:
(
previousDir
&&
previousDir
.
neng
!==
0
)
?
parseFloat
(((
currentDir
.
neng
-
previousDir
.
neng
)
/
previousDir
.
neng
*
100
).
toFixed
(
2
))
:
null
}
};
const
currentTotal
=
getFieldValue
(
currentRecord
,
'total_score'
)
||
0
;
const
previousTotal
=
previousRecord
?
getFieldValue
(
previousRecord
,
'total_score'
)
:
null
;
const
lionImageInfo
=
await
getLionImageByScores
({
公
:
currentDir
.
gong
,
智
:
currentDir
.
zhi
,
能
:
currentDir
.
neng
});
return
{
student_id
,
student_name
:
getFieldValue
(
currentRecord
,
'student_name'
)
||
''
,
hasData
:
true
,
message
:
'获取成功'
,
currentAnswerTime
:
getFieldValue
(
currentRecord
,
'answer_time'
),
previousAnswerTime
:
previousRecord
?
getFieldValue
(
previousRecord
,
'answer_time'
)
:
null
,
abilities
,
directionScores
:
{
gong
:
{
...
directionScores
.
gong
,
description
:
getScoreDescription
(
directionScores
.
gong
.
currentScore
)
},
zhi
:
{
...
directionScores
.
zhi
,
description
:
getScoreDescription
(
directionScores
.
zhi
.
currentScore
)
},
neng
:
{
...
directionScores
.
neng
,
description
:
getScoreDescription
(
directionScores
.
neng
.
currentScore
)
}
},
totalScore
:
{
currentScore
:
currentTotal
,
previousScore
:
previousTotal
,
yoyChange
:
previousTotal
!==
null
?
currentTotal
-
previousTotal
:
null
,
yoyPercent
:
(
previousTotal
!==
null
&&
previousTotal
!==
0
)
?
parseFloat
(((
currentTotal
-
previousTotal
)
/
previousTotal
*
100
).
toFixed
(
2
))
:
null
,
description
:
getScoreDescription
(
currentTotal
)
},
lionImageInfo
};
}
function
getEmptyResult
(
student_id
:
string
)
{
const
defaultLion
=
getDefaultLionImage
();
const
abilitiesKeys
=
[
'jgqh'
,
'gjsy'
,
'zrdd'
,
'xyzs'
,
'yycx'
,
'syxx'
,
'jksh'
,
'smqq'
,
'ldys'
];
const
abilitiesNames
:
Record
<
string
,
string
>
=
{
jgqh
:
'家国情怀'
,
gjsy
:
'国际视野'
,
zrdd
:
'责任担当'
,
xyzs
:
'学业扎实'
,
yycx
:
'勇于创新'
,
syxx
:
'善于学习'
,
jksh
:
'健康生活'
,
smqq
:
'审美情趣'
,
ldys
:
'劳动意识'
};
const
abilities
:
any
=
{};
for
(
const
key
of
abilitiesKeys
)
{
abilities
[
key
]
=
{
name
:
abilitiesNames
[
key
],
currentScore
:
0
,
previousScore
:
null
,
yoyChange
:
null
,
yoyPercent
:
null
};
}
return
{
student_id
,
student_name
:
''
,
hasData
:
false
,
message
:
'该学生暂无答题记录'
,
currentAnswerTime
:
null
,
previousAnswerTime
:
null
,
abilities
,
directionScores
:
{
gong
:
{
name
:
'公'
,
currentScore
:
0
,
previousScore
:
null
,
yoyChange
:
null
,
yoyPercent
:
null
,
description
:
'待提升'
},
zhi
:
{
name
:
'智'
,
currentScore
:
0
,
previousScore
:
null
,
yoyChange
:
null
,
yoyPercent
:
null
,
description
:
'待提升'
},
neng
:
{
name
:
'能'
,
currentScore
:
0
,
previousScore
:
null
,
yoyChange
:
null
,
yoyPercent
:
null
,
description
:
'待提升'
}
},
totalScore
:
{
currentScore
:
0
,
previousScore
:
null
,
yoyChange
:
null
,
yoyPercent
:
null
,
description
:
'待提升'
},
lionImageInfo
:
defaultLion
};
}
// ==================== 简化版导出(可选) ====================
export
async
function
getStudentAbilityScoresSimple
(
student_id
:
string
)
{
const
result
=
await
getStudentAbilityScoresWithComparison
(
student_id
);
if
(
!
result
.
hasData
)
{
return
{
student_id
,
hasData
:
false
,
message
:
result
.
message
,
currentAnswerTime
:
null
,
previousAnswerTime
:
null
,
currentScores
:
[
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
],
previousScores
:
null
,
yoyChanges
:
null
,
totalScore
:
result
.
totalScore
,
directionScores
:
result
.
directionScores
,
lionImageInfo
:
result
.
lionImageInfo
};
}
const
currentScores
=
[
result
.
abilities
.
jgqh
.
currentScore
,
result
.
abilities
.
gjsy
.
currentScore
,
result
.
abilities
.
zrdd
.
currentScore
,
result
.
abilities
.
xyzs
.
currentScore
,
result
.
abilities
.
yycx
.
currentScore
,
result
.
abilities
.
syxx
.
currentScore
,
result
.
abilities
.
jksh
.
currentScore
,
result
.
abilities
.
smqq
.
currentScore
,
result
.
abilities
.
ldys
.
currentScore
];
const
previousScores
=
result
.
abilities
.
jgqh
.
previousScore
!==
null
?
[
result
.
abilities
.
jgqh
.
previousScore
,
result
.
abilities
.
gjsy
.
previousScore
,
result
.
abilities
.
zrdd
.
previousScore
,
result
.
abilities
.
xyzs
.
previousScore
,
result
.
abilities
.
yycx
.
previousScore
,
result
.
abilities
.
syxx
.
previousScore
,
result
.
abilities
.
jksh
.
previousScore
,
result
.
abilities
.
smqq
.
previousScore
,
result
.
abilities
.
ldys
.
previousScore
]
:
null
;
const
yoyChanges
=
result
.
abilities
.
jgqh
.
yoyChange
!==
null
?
[
result
.
abilities
.
jgqh
.
yoyChange
,
result
.
abilities
.
gjsy
.
yoyChange
,
result
.
abilities
.
zrdd
.
yoyChange
,
result
.
abilities
.
xyzs
.
yoyChange
,
result
.
abilities
.
yycx
.
yoyChange
,
result
.
abilities
.
syxx
.
yoyChange
,
result
.
abilities
.
jksh
.
yoyChange
,
result
.
abilities
.
smqq
.
yoyChange
,
result
.
abilities
.
ldys
.
yoyChange
]
:
null
;
return
{
student_id
,
student_name
:
result
.
student_name
,
hasData
:
true
,
message
:
result
.
message
,
currentAnswerTime
:
result
.
currentAnswerTime
,
previousAnswerTime
:
result
.
previousAnswerTime
,
currentScores
,
previousScores
,
yoyChanges
,
totalScore
:
result
.
totalScore
,
directionScores
:
result
.
directionScores
,
lionImageInfo
:
result
.
lionImageInfo
};
}
src/main.ts
View file @
654a48d6
...
@@ -20,7 +20,7 @@ async function lanuch() {
...
@@ -20,7 +20,7 @@ async function lanuch() {
console
.
log
(
'This indicates that the server is started successfully.'
);
console
.
log
(
'This indicates that the server is started successfully.'
);
backup
();
//
backup();
// 应用启动时初始化UAC集成
// 应用启动时初始化UAC集成
const
xmlRpcServer
=
await
initUACIntegration
();
const
xmlRpcServer
=
await
initUACIntegration
();
...
@@ -29,6 +29,7 @@ async function lanuch() {
...
@@ -29,6 +29,7 @@ async function lanuch() {
}
else
{
}
else
{
console
.
error
(
'🔴 XML-RPC服务器启动失败'
);
console
.
error
(
'🔴 XML-RPC服务器启动失败'
);
}
}
}
}
lanuch
();
lanuch
();
...
...
src/routers/router.ts
View file @
654a48d6
...
@@ -3,7 +3,9 @@
...
@@ -3,7 +3,9 @@
*/
*/
import
*
as
questionRouter
from
'./question'
;
import
*
as
questionRouter
from
'./question'
;
import
*
as
throwMethodRouter
from
'./throwMethod'
;
export
function
setRouter
(
httpServer
){
export
function
setRouter
(
httpServer
){
questionRouter
.
setRouter
(
httpServer
);
questionRouter
.
setRouter
(
httpServer
);
throwMethodRouter
.
setRouter
(
httpServer
);
}
}
src/routers/throwMethod.ts
0 → 100644
View file @
654a48d6
/**
* 公智能评价答题 - 能力同比分析路由
*/
import
asyncHandler
from
'express-async-handler'
;
import
*
as
throwMethodBiz
from
'../biz/throwMethod'
;
import
{
checkUser
}
from
'../middleware/user'
;
export
function
setRouter
(
httpServer
)
{
/**学生能力同比分析接口 */
// 获取学生九大能力得分及同比数据(完整版)
httpServer
.
post
(
'/gzn/throwmethod/abilitycomparison'
,
asyncHandler
(
getStudentAbilityComparison
));
// 获取学生九大能力得分及同比数据(简化版,用于图表)
httpServer
.
post
(
'/gzn/throwmethod/abilitycomparisonsimple'
,
asyncHandler
(
getStudentAbilityComparisonSimple
));
// 批量获取多个学生的能力同比数据
httpServer
.
post
(
'/gzn/throwmethod/batchabilitycomparison'
,
asyncHandler
(
getBatchStudentAbilityComparison
));
}
/**
* 获取学生九大能力得分及同比数据(完整版)
* @param req - 请求对象
* @param res - 响应对象
*
* 请求参数:
* - student_id?: string - 学生ID(可选,不传则使用当前登录用户)
*/
async
function
getStudentAbilityComparison
(
req
,
res
)
{
const
UserInfo
=
req
.
userInfo
;
let
{
student_id
}
=
req
.
body
;
// 如果没有传student_id,使用当前登录用户的ID
const
targetStudentId
=
student_id
||
UserInfo
.
studentId
;
let
result
=
await
throwMethodBiz
.
getStudentAbilityScoresWithComparison
(
targetStudentId
);
res
.
success
(
result
);
}
/**
* 获取学生九大能力得分及同比数据(简化版,仅返回数值数组,用于图表展示)
* @param req - 请求对象
* @param res - 响应对象
*
* 请求参数:
* - student_id?: string - 学生ID(可选,不传则使用当前登录用户)
*/
async
function
getStudentAbilityComparisonSimple
(
req
,
res
)
{
const
UserInfo
=
req
.
userInfo
;
let
{
student_id
}
=
req
.
body
;
// 如果没有传student_id,使用当前登录用户的ID
const
targetStudentId
=
student_id
||
UserInfo
.
studentId
;
let
result
=
await
throwMethodBiz
.
getStudentAbilityScoresSimple
(
targetStudentId
);
res
.
success
(
result
);
}
/**
* 批量获取多个学生的九大能力得分及同比数据
* @param req - 请求对象
* @param res - 响应对象
*
* 请求参数:
* - student_ids: string[] - 学生ID数组(必填)
*/
async
function
getBatchStudentAbilityComparison
(
req
,
res
)
{
const
UserInfo
=
req
.
userInfo
;
let
{
student_ids
}
=
req
.
body
;
if
(
!
student_ids
||
!
Array
.
isArray
(
student_ids
)
||
student_ids
.
length
===
0
)
{
throw
new
Error
(
'学生ID列表不能为空'
);
}
const
results
=
[];
for
(
const
student_id
of
student_ids
)
{
try
{
const
result
=
await
throwMethodBiz
.
getStudentAbilityScoresWithComparison
(
student_id
);
results
.
push
(
result
);
}
catch
(
error
)
{
results
.
push
({
student_id
,
hasData
:
false
,
message
:
error
.
message
||
'获取数据失败'
});
}
}
res
.
success
({
total
:
results
.
length
,
list
:
results
});
}
tsconfig.json
View file @
654a48d6
...
@@ -6,7 +6,11 @@
...
@@ -6,7 +6,11 @@
"rootDir"
:
"./src"
,
"rootDir"
:
"./src"
,
"outDir"
:
"./out"
,
"outDir"
:
"./out"
,
"esModuleInterop"
:
true
,
"esModuleInterop"
:
true
,
//
"strict"
:
true
,
"allowSyntheticDefaultImports"
:
true
,
"strict"
:
false
,
"noImplicitAny"
:
false
,
"strictNullChecks"
:
false
,
"types"
:
[
"node"
]
},
},
"exclude"
:
[
"exclude"
:
[
"node_modules"
,
"node_modules"
,
...
...
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