diff --git a/internal/domains/api/services/processors/ivyz/ivyz3p9m_processor copy.go b/internal/domains/api/services/processors/ivyz/ivyz3p9m_processor copy.go new file mode 100644 index 0000000..d0f939a --- /dev/null +++ b/internal/domains/api/services/processors/ivyz/ivyz3p9m_processor copy.go @@ -0,0 +1,64 @@ +package ivyz + +import ( + "context" + "encoding/json" + "errors" + + "tyapi-server/internal/domains/api/dto" + "tyapi-server/internal/domains/api/services/processors" + "tyapi-server/internal/infrastructure/external/muzi" +) + +// ProcessIVYZ3P9MRequest IVYZ3P9M API处理方法 - 学历查询实时版 +func ProcessIVYZ3P9MRequest_2(ctx context.Context, params []byte, deps *processors.ProcessorDependencies) ([]byte, error) { + var paramsDto dto.IVYZ3P9MReq + if err := json.Unmarshal(params, ¶msDto); err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + + if err := deps.Validator.ValidateStruct(paramsDto); err != nil { + return nil, errors.Join(processors.ErrInvalidParam, err) + } + + encryptedName, err := deps.MuziService.Encrypt(paramsDto.Name) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + + encryptedCertCode, err := deps.MuziService.Encrypt(paramsDto.IDCard) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + + // 处理 returnType 参数,默认为 "1" + returnType := paramsDto.ReturnType + if returnType == "" { + returnType = "1" + } + paramSign := map[string]interface{}{ + "returnType": returnType, + "realName": encryptedName, + "certCode": encryptedCertCode, + } + + reqData := map[string]interface{}{ + "realName": encryptedName, + "certCode": encryptedCertCode, + "returnType": returnType, + } + + respData, err := deps.MuziService.CallAPI(ctx, "PC0041", "/academic", reqData, paramSign) + if err != nil { + switch { + case errors.Is(err, muzi.ErrDatasource): + return nil, errors.Join(processors.ErrDatasource, err) + case errors.Is(err, muzi.ErrSystem): + return nil, errors.Join(processors.ErrSystem, err) + default: + return nil, errors.Join(processors.ErrSystem, err) + } + } + + return respData, nil +} diff --git a/internal/domains/api/services/processors/ivyz/ivyz3p9m_processor.go b/internal/domains/api/services/processors/ivyz/ivyz3p9m_processor.go index 6341304..f38ad48 100644 --- a/internal/domains/api/services/processors/ivyz/ivyz3p9m_processor.go +++ b/internal/domains/api/services/processors/ivyz/ivyz3p9m_processor.go @@ -4,10 +4,11 @@ import ( "context" "encoding/json" "errors" + "strings" "tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/services/processors" - "tyapi-server/internal/infrastructure/external/muzi" + "tyapi-server/internal/infrastructure/external/zhicha" ) // ProcessIVYZ3P9MRequest IVYZ3P9M API处理方法 - 学历查询实时版 @@ -21,45 +22,147 @@ func ProcessIVYZ3P9MRequest(ctx context.Context, params []byte, deps *processors return nil, errors.Join(processors.ErrInvalidParam, err) } - encryptedName, err := deps.MuziService.Encrypt(paramsDto.Name) + encryptedName, err := deps.ZhichaService.Encrypt(paramsDto.Name) if err != nil { return nil, errors.Join(processors.ErrSystem, err) } - encryptedCertCode, err := deps.MuziService.Encrypt(paramsDto.IDCard) + encryptedIDCard, err := deps.ZhichaService.Encrypt(paramsDto.IDCard) if err != nil { return nil, errors.Join(processors.ErrSystem, err) } - // 处理 returnType 参数,默认为 "1" - returnType := paramsDto.ReturnType - if returnType == "" { - returnType = "1" - } - paramSign := map[string]interface{}{ - "returnType": returnType, - "realName": encryptedName, - "certCode": encryptedCertCode, - } - reqData := map[string]interface{}{ - "realName": encryptedName, - "certCode": encryptedCertCode, - "returnType": returnType, + "name": encryptedName, + "idCard": encryptedIDCard, + "authorized": "1", } - - respData, err := deps.MuziService.CallAPI(ctx, "PC0041", "/academic",reqData,paramSign) + respData, err := deps.ZhichaService.CallAPI(ctx, "ZCI1004", reqData) if err != nil { - switch { - case errors.Is(err, muzi.ErrDatasource): + if errors.Is(err, zhicha.ErrDatasource) { return nil, errors.Join(processors.ErrDatasource, err) - case errors.Is(err, muzi.ErrSystem): - return nil, errors.Join(processors.ErrSystem, err) - default: - return nil, errors.Join(processors.ErrSystem, err) + } + return nil, errors.Join(processors.ErrSystem, err) + } + + out, err := mapZCI1004ToIVYZ3P9M(respData, paramsDto.Name, paramsDto.IDCard) + if err != nil { + return nil, errors.Join(processors.ErrSystem, err) + } + return json.Marshal(out) +} + +type zci1004Item struct { + EndDate string `json:"endDate"` + EducationLevel string `json:"educationLevel"` + LearningForm string `json:"learningForm"` +} + +type ivyz3p9mItem struct { + GraduationDate string `json:"graduationDate"` + StudentName string `json:"studentName"` + EducationLevel string `json:"educationLevel"` + LearningForm string `json:"learningForm"` + IDNumber string `json:"idNumber"` +} + +func mapZCI1004ToIVYZ3P9M(respData interface{}, name, idCard string) ([]ivyz3p9mItem, error) { + respBytes, err := json.Marshal(respData) + if err != nil { + return nil, err + } + + var source []zci1004Item + if err := json.Unmarshal(respBytes, &source); err != nil { + var wrapped struct { + Data []zci1004Item `json:"data"` + } + if err2 := json.Unmarshal(respBytes, &wrapped); err2 != nil { + return nil, err + } + source = wrapped.Data + } + + out := make([]ivyz3p9mItem, 0, len(source)) + for _, it := range source { + out = append(out, ivyz3p9mItem{ + GraduationDate: normalizeDateDigits(it.EndDate), + StudentName: name, + EducationLevel: mapEducationLevelToCode(it.EducationLevel), + LearningForm: mapLearningFormToCode(it.LearningForm), + IDNumber: idCard, + }) + } + + return out, nil +} + +func mapEducationLevelToCode(level string) string { + v := normalizeText(level) + switch { + case strings.Contains(v, "第二学士"): + return "5" + case strings.Contains(v, "博士"): + return "4" + case strings.Contains(v, "硕士"): + return "3" + case strings.Contains(v, "本科"): + return "2" + case strings.Contains(v, "专科"), strings.Contains(v, "大专"): + return "1" + default: + return "99" + } +} + +func mapLearningFormToCode(form string) string { + v := normalizeText(form) + switch { + case strings.Contains(v, "脱产"): + return "1" + case strings.Contains(v, "普通全日制"): + return "2" + case strings.Contains(v, "全日制"): + return "3" + case strings.Contains(v, "开放教育"), strings.Contains(v, "开放大学"): + return "4" + case strings.Contains(v, "夜大学"), strings.Contains(v, "夜大"): + return "5" + case strings.Contains(v, "函授"): + return "6" + case strings.Contains(v, "网络教育"), strings.Contains(v, "网教"), strings.Contains(v, "远程教育"): + return "7" + case strings.Contains(v, "非全日制"): + return "8" + case strings.Contains(v, "业余"): + return "9" + case strings.Contains(v, "自学考试"), strings.Contains(v, "自考"): + // 自考在既有枚举中无直对应,兼容并入“业余” + return "9" + default: + return "99" + } +} + +func normalizeDateDigits(s string) string { + trimmed := strings.TrimSpace(s) + if trimmed == "" { + return "" + } + var b strings.Builder + for _, ch := range trimmed { + if ch >= '0' && ch <= '9' { + b.WriteRune(ch) } } - - return respData, nil + return b.String() +} + +func normalizeText(s string) string { + v := strings.TrimSpace(strings.ToLower(s)) + v = strings.ReplaceAll(v, " ", "") + v = strings.ReplaceAll(v, "-", "") + v = strings.ReplaceAll(v, "_", "") + return v }