testfb/handlers/student.go
2024-10-09 08:38:01 +08:00

223 lines
7.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handlers
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"testfb/config"
"testfb/models"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/storage/redis/v3"
)
// POST 根据身份证和token来获取家长或老师的基本信息
func GetUserInfo(isStudent bool, redisClient *redis.Storage) fiber.Handler {
return func(c *fiber.Ctx) error {
// 获取POST 请求参数
var apiUser models.ReqApi
if err := c.BodyParser(&apiUser); err != nil {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取信息失败,参数错误",
"error": err.Error(),
})
}
nationalId := apiUser.NationalId
if nationalId == "" {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取信息失败,身份证不能为空",
"error": "身份证不能为空",
})
}
cfg := config.New()
token, err := getEKTPlatformToken(redisClient)
if err != nil {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取token失败,",
"error": err.Error(),
})
}
// 验证身份证有效性
url := cfg.APIUserUrl
if isStudent {
url = cfg.APIStudentUrl
}
reqBody := map[string]string{
"token": token,
"nationalId": nationalId,
}
reqBodyJson, _ := json.Marshal(reqBody)
req, err := http.Post(url, "application/json", bytes.NewBuffer(reqBodyJson))
if err != nil {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取身份信息失败,无法解析URL",
"error": err.Error(),
})
}
defer req.Body.Close()
body, _ := io.ReadAll(req.Body)
// 解析返回的json数据判断是否有code字段并且code是否为1如果是则获取并返回token
var result map[string]interface{}
json.Unmarshal(body, &result)
fmt.Println(result)
if _, ok := result["code"]; !ok || int(result["code"].(float64)) != 1 {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取身份信息失败,身份证无效",
"error": "身份证无效",
})
}
// 如果身份正常,则返回所有信息
return c.JSON(result)
}
}
// 根据家长身份证或手机号、token获取学生的基本信息其中家长身份证或手机号二选一如果都不传则返回错误信息如果都传则只判断身份证号
func GetStudentInfoByParent(redisClient *redis.Storage) fiber.Handler {
return func(c *fiber.Ctx) error {
// 获取POST 请求参数
var apiUser models.ReqApi
if err := c.BodyParser(&apiUser); err != nil {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取信息失败,参数错误",
"error": err.Error(),
})
}
nationalId := apiUser.NationalId
phone := apiUser.Phone
if nationalId == "" && phone == "" {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取学生信息失败,身份证或手机号不能为空",
"error": "身份证或手机号不能为空",
})
}
cfg := config.New()
token, err := getEKTPlatformToken(redisClient)
if err != nil {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取token失败,",
"error": err.Error(),
})
}
// 验证身份证有效性
url := cfg.APIParentUrl
var reqBody map[string]string
reqBody = map[string]string{
"token": token,
"nationalId": nationalId,
"phone": phone,
}
reqBodyJson, _ := json.Marshal(reqBody)
req, err := http.Post(url, "application/json", bytes.NewBuffer(reqBodyJson))
if err != nil {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取学生信息失败,无法解析URL",
"error": err.Error(),
})
}
defer req.Body.Close()
body, _ := io.ReadAll(req.Body)
// 解析返回的json数据判断是否有code字段并且code是否为1如果是则获取并返回token
var result map[string]interface{}
json.Unmarshal(body, &result)
if _, ok := result["code"]; !ok || int(result["code"].(float64)) != 1 {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取学生信息失败,身份证或手机号无效",
"error": "身份证或手机号无效",
})
}
// 如果身份正常,则返回所有信息
return c.JSON(result)
}
}
// Redis中 取数据
func getEKTPlatformToken(redisClient *redis.Storage) (string, error) {
userIDBytes, err := redisClient.Get("testToken")
if err != nil {
return "", errors.New("获取token失败,redis错误")
}
if userIDBytes != nil {
token := string(userIDBytes)
// 验证token有效性
isValid, err := verifyToken(token)
if err != nil {
return "", errors.New(err.Error())
}
if isValid {
return token, nil
}
}
// token无效重新获取token
token, err := fetchTokenFromAPI()
if err != nil {
return "", errors.New(err.Error())
}
redisClient.Set("testToken", []byte(token), 3600)
return token, nil
}
func fetchTokenFromAPI() (string, error) {
cfg := config.New()
url := cfg.APITokenUrl
username := cfg.APIUser
password := cfg.APIPassword
reqBody := map[string]string{
"name": username,
"password": password,
}
reqBodyJson, _ := json.Marshal(reqBody)
fmt.Println(string(reqBodyJson))
returnValue, err := http.Post(url, "application/json", bytes.NewBuffer(reqBodyJson))
if err != nil {
return "", errors.New("获取token失败,无法解析 token URL")
}
defer returnValue.Body.Close()
body, _ := io.ReadAll(returnValue.Body)
fmt.Println(string(body))
// 解析返回的json数据判断是否有code字段并且code是否为1如果是则获取并返回token
var result map[string]interface{}
json.Unmarshal(body, &result)
// 如果不存在code 字段则token无效。如果存在code强制类型转换为int判断code是否为1如果不是1则token无效
if _, ok := result["code"]; !ok {
return "", errors.New("fetchTokenFromAPI:获取token失败,token无效,code字段不存在")
}
code := int(result["code"].(float64))
if code != 1 {
return "", errors.New("fetchTokenFromAPI:获取token失败,token无效,code:" + fmt.Sprintf("%d", code) + " message:" + result["message"].(string))
}
// 如果不存在result字段或result字段的值为空则token为空
if _, ok := result["result"]; !ok || result["result"] == "" {
return "", errors.New("获取token失败,token为空")
}
return result["result"].(string), nil
}
// 验证接口有效性
func verifyToken(token string) (bool, error) {
cfg := config.New()
url := cfg.APIUserUrl
reqBody := map[string]string{
"token": token,
"nationalId": "123",
}
reqBodyJson, _ := json.Marshal(reqBody)
req, err := http.Post(url, "application/json", bytes.NewBuffer(reqBodyJson))
if err != nil {
return false, errors.New("验证token失败,无法解析URL")
}
defer req.Body.Close()
body, _ := io.ReadAll(req.Body)
// 解析返回的json数据判断是否有code字段并且code是否为1如果是则获取并返回token
var result map[string]interface{}
json.Unmarshal(body, &result)
// 如果不存在code 字段或者code字段的值不是1则token无效
if _, ok := result["code"]; !ok || result["code"] != 1 {
return false, errors.New("验证token失败,token无效")
}
return true, nil
}