This commit is contained in:
dandan 2024-09-22 22:26:20 +08:00
parent 42d392ddba
commit 2347120cd3
2 changed files with 43 additions and 26 deletions

View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration"> <component name="FrameworkDetectionExcludesConfiguration">

View File

@ -3,6 +3,8 @@ package org.echo.questionnaire
import kotlin.math.abs import kotlin.math.abs
import kotlin.random.Random import kotlin.random.Random
class Questionnaire( class Questionnaire(
val id: Long, val id: Long,
val title: String, // 问卷的标题 val title: String, // 问卷的标题
@ -10,7 +12,7 @@ class Questionnaire(
val questions: List<SurveyQuestion>, val questions: List<SurveyQuestion>,
val questionGroup: List<QuestionGroup>, val questionGroup: List<QuestionGroup>,
val sample: SurveyBackgroundSample, // 问卷中的所有问题 val sample: SurveyBackgroundSample, // 问卷中的所有问题
val procedures: List<SurveyProcedure> val procedures: List<SurveyProcedure>,
) { ) {
private val selectedOptions: MutableMap<Long, MutableSet<Long>> = mutableMapOf()// Map of questionId to optionId private val selectedOptions: MutableMap<Long, MutableSet<Long>> = mutableMapOf()// Map of questionId to optionId
@ -39,7 +41,7 @@ class Questionnaire(
// Identify target questions influenced by the source question // Identify target questions influenced by the source question
val influencedQuestionIds = getInfluencedQuestionIdsInGroup(questionId) val influencedQuestionIds = getInfluencedQuestionIdsInGroup(questionId)
for (targetQuestionId in influencedQuestionIds) { for (targetQuestionId in influencedQuestionIds) {
addDependenciesAfterAnswer(this, questionId, optionId,targetQuestionId) addDependenciesAfterAnswer(this, questionId, optionId, targetQuestionId)
} }
// Recalculate weights for all options that might be affected // Recalculate weights for all options that might be affected
@ -61,7 +63,7 @@ class Questionnaire(
questionnaire: Questionnaire, questionnaire: Questionnaire,
sourceQuestionId: Long, sourceQuestionId: Long,
sourceOptionId: Long, sourceOptionId: Long,
targetQuestionId: Long targetQuestionId: Long,
) { ) {
val influencedOptionSet = questionnaire.getSelectedOption(sourceQuestionId) val influencedOptionSet = questionnaire.getSelectedOption(sourceQuestionId)
val targetQuestion = questionnaire.questions.map { it.question }.find { it.id == targetQuestionId } val targetQuestion = questionnaire.questions.map { it.question }.find { it.id == targetQuestionId }
@ -73,14 +75,19 @@ class Questionnaire(
// Remove existing dependencies from the same source question // Remove existing dependencies from the same source question
val dependency = OptionDependency( val dependency = OptionDependency(
sourceQuestionId = sourceQuestionId, sourceQuestionId = sourceQuestionId,
sourceOptionId = influencedOption.id, sourceOptionId = sourceOptionId,
targetOptionId = targetOption.id, influencedOptionId = influencedOption.id,
targetOptionId = targetQuestion.id,
condition = { q -> condition = { q ->
q.isOptionSelected(sourceQuestionId, sourceOptionId) q.isOptionSelected(sourceQuestionId, sourceOptionId)
}, },
effect = { _ -> effect = { _ ->
// Define your effect based on source and target options // 使用枚举类的 calculateEffectBasedOnOrder 方法
calculateEffectBasedOnOrder(influencedOption, targetOption) val effectValue = ComputeMethod.BaseComputeMethod
.calculateEffectBasedOnOrder(influencedOption, targetOption)
// 根据计算结果进行相应处理
println("Effect calculated: $effectValue")
effectValue // 返回 effect 值,这个可以用于后续的逻辑
} }
) )
targetOption.addDependency(dependency) targetOption.addDependency(dependency)
@ -90,7 +97,7 @@ class Questionnaire(
fun calculateEffectBasedOnOrder( fun calculateEffectBasedOnOrder(
influencedOption: QuestionOption, influencedOption: QuestionOption,
targetOption: QuestionOption targetOption: QuestionOption, //是他自己
): Double { ): Double {
val orderDifference = abs(influencedOption.markOrder - targetOption.markOrder) val orderDifference = abs(influencedOption.markOrder - targetOption.markOrder)
return when (orderDifference) { return when (orderDifference) {
@ -148,7 +155,7 @@ open class Question(
val optionList: List<QuestionOption>, val optionList: List<QuestionOption>,
val questionType: QuestionType, // 表示问题类型:单选、多选、开放式等 val questionType: QuestionType, // 表示问题类型:单选、多选、开放式等
val order: Int, // 表示问题顺序 val order: Int, // 表示问题顺序
val isRequired: Boolean = true // 是否必答,默认为必答 val isRequired: Boolean = true, // 是否必答,默认为必答
) { ) {
fun getOptionListData(): List<QuestionOption> { fun getOptionListData(): List<QuestionOption> {
return optionList return optionList
@ -162,7 +169,7 @@ class QuestionGroup(
val parentId: Long, val parentId: Long,
val groupName: String, val groupName: String,
val surveyQuestionList: List<SurveyQuestion>, val surveyQuestionList: List<SurveyQuestion>,
var answeredQuestions: MutableMap<SurveyQuestion, QuestionOption> = mutableMapOf() // 已回答的问题及其分数 var answeredQuestions: MutableMap<SurveyQuestion, QuestionOption> = mutableMapOf(), // 已回答的问题及其分数
) { ) {
fun checkIfInGroup(questionId: Long): Boolean { fun checkIfInGroup(questionId: Long): Boolean {
return surveyQuestionList.map { it.question }.any { it.id == questionId } return surveyQuestionList.map { it.question }.any { it.id == questionId }
@ -176,7 +183,7 @@ class QuestionOption(
val mark: String, val mark: String,
val markOrder: Int, val markOrder: Int,
val score: Int? = null, // 可选的分数字段 val score: Int? = null, // 可选的分数字段
var dependencies: MutableList<OptionDependency> = mutableListOf() // 与其他选项的依赖关系 var dependencies: MutableList<OptionDependency> = mutableListOf(), // 与其他选项的依赖关系
) { ) {
// 计算依赖关系对权重的影响 // 计算依赖关系对权重的影响
fun calculateWeightWithDependencies(questionnaire: Questionnaire): Double { fun calculateWeightWithDependencies(questionnaire: Questionnaire): Double {
@ -209,9 +216,10 @@ class QuestionOptionWeight(
class OptionDependency( class OptionDependency(
val sourceQuestionId: Long, val sourceQuestionId: Long,
val sourceOptionId: Long, val sourceOptionId: Long,
val influencedOptionId: Long,
val targetOptionId: Long, val targetOptionId: Long,
val condition: (Questionnaire) -> Boolean, val condition: (Questionnaire) -> Boolean,
val effect: (Questionnaire) -> Double val effect: (Questionnaire) -> Double,
) )
@ -236,17 +244,17 @@ class SurveyQuestion(
class SurveyBackgroundSample( class SurveyBackgroundSample(
val surveyRespondent: SurveyRespondent, val surveyRespondent: SurveyRespondent,
val surveyBackgroundList: List<SurveyBackground> val surveyBackgroundList: List<SurveyBackground>,
) )
class SurveyRespondent( class SurveyRespondent(
val name: String, val name: String,
val age: Int val age: Int,
) )
class SurveyBackground( class SurveyBackground(
val title: String, val title: String,
val backgroundQuestion: Question val backgroundQuestion: Question,
) )
class SurveyProcedure( class SurveyProcedure(
@ -255,37 +263,47 @@ class SurveyProcedure(
val sourceOptionId: Long, val sourceOptionId: Long,
val influencedQuestionId: Long, val influencedQuestionId: Long,
val influencedOptionId: Long, val influencedOptionId: Long,
val computeMethod: ComputeMethod = ComputeMethod.BaseComputeMethod val computeMethod: ComputeMethod = ComputeMethod.BaseComputeMethod,
) { ) {
fun ifProcess(sourceOptionalId: Long, questionnaire: Questionnaire) { fun ifProcess(sourceOptionalId: Long, questionnaire: Questionnaire) {
if (sourceOptionalId == sourceOptionId) generateOptionDependency(questionnaire) if (sourceOptionalId == sourceOptionId) generateOptionDependency(questionnaire)
} }
fun generateOptionDependency(questionnaire: Questionnaire): OptionDependency? { fun generateOptionDependency(questionnaire: Questionnaire) {
val influencedQuestionOptions = questionnaire.questions val influencedQuestionOptions = questionnaire.questions
.filter { it.questionId == influencedQuestionId } .filter { it.questionId == influencedQuestionId }
.map { it.question } .map { it.question }
.flatMap { it.optionList } .flatMap { it.optionList }
val influencedOption = influencedQuestionOptions val influencedOption = influencedQuestionOptions
.filter { option -> option.id == influencedOptionId } .filter { option -> option.id == influencedOptionId }
.last()
influencedQuestionOptions.forEach { influencedQuestionOptions.forEach {
//遍历所有的选项,向其中加入选项依赖 //遍历所有的选项,向其中加入选项依赖
OptionDependency(sourceOptionId,sourceOptionId,) val optionDependency = OptionDependency(
sourceOptionId, sourceOptionId,
influencedOption.id,
it.id,
condition = { q ->
q.isOptionSelected(sourceQuestionId, sourceOptionId)
},
effect = { _ ->
// Define your effect based on source and target options
computeMethod.calculateEffectBasedOnOrder(influencedOption, it)
}
)
it.addDependency(optionDependency)
} }
return null
} }
} }
enum class ComputeMethod( enum class ComputeMethod(
val computeMethodName: String val computeMethodName: String,
) { ) {
BaseComputeMethod("Default") { BaseComputeMethod("Default") {
override fun calculateEffectBasedOnOrder( override fun calculateEffectBasedOnOrder(
influencedOption: QuestionOption, influencedOption: QuestionOption,
targetOption: QuestionOption targetOption: QuestionOption,
): Double { ): Double {
val orderDifference = abs(influencedOption.markOrder - targetOption.markOrder) val orderDifference = abs(influencedOption.markOrder - targetOption.markOrder)
return when (orderDifference) { return when (orderDifference) {
@ -300,6 +318,6 @@ enum class ComputeMethod(
// 定义抽象方法,子类必须实现 // 定义抽象方法,子类必须实现
abstract fun calculateEffectBasedOnOrder( abstract fun calculateEffectBasedOnOrder(
sourceOption: QuestionOption, sourceOption: QuestionOption,
targetOption: QuestionOption targetOption: QuestionOption,
): Double ): Double
} }