testfb/middleware/student.go
2024-10-08 20:15:31 +08:00

262 lines
8.5 KiB
Go
Raw 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 middleware
import (
"bytes"
"encoding/json"
"errors"
"io"
"net/http"
"testfb/config"
"testfb/models"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/storage/redis/v3"
)
// POST 根据身份证和token来获取家长或老师的基本信息
func GetUserInfo(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, cfg.APIUser, cfg.APIPassword)
if err != nil {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取token失败,",
"error": err.Error(),
})
}
// 验证身份证有效性
url := cfg.APIUserUrl
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)
if _, ok := result["code"]; !ok || result["code"] != 1 {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取学生信息失败,身份证无效",
"error": "身份证无效",
})
}
// 如果身份正常,则返回所有信息
return c.JSON(result)
}
}
// 根据学生身份证和token获取学生的基本信息
func GetStudentInfo(redisClient *redis.Storage) fiber.Handler {
return func(c *fiber.Ctx) error {
// 获取POST 请求参数
nationalId := c.Params("nationalId")
if nationalId == "" {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取学生信息失败,身份证不能为空",
"error": "身份证不能为空",
})
}
cfg := config.New()
token, err := getEKTPlatformToken(redisClient, cfg.APIUser, cfg.APIPassword)
if err != nil {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取token失败,",
"error": err.Error(),
})
}
// 验证身份证有效性
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)
if _, ok := result["code"]; !ok || result["code"] != 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 请求参数
nationalId := c.Params("nationalId")
mobile := c.Params("mobile")
if nationalId == "" && mobile == "" {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取学生信息失败,身份证或手机号不能为空",
"error": "身份证或手机号不能为空",
})
}
cfg := config.New()
token, err := getEKTPlatformToken(redisClient, cfg.APIUser, cfg.APIPassword)
if err != nil {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取token失败,",
"error": err.Error(),
})
}
// 验证身份证有效性
url := cfg.APIParentUrl
var reqBody map[string]string
if nationalId != "" {
reqBody = map[string]string{
"token": token,
"nationalId": nationalId,
}
} else if mobile != "" {
reqBody = map[string]string{
"token": token,
"mobile": mobile,
}
} else {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取学生信息失败,身份证或手机号不能为空",
"error": "身份证或手机号不能为空",
})
}
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 || result["code"] != 1 {
return c.Status(http.StatusUnauthorized).JSON(fiber.Map{
"message": "获取学生信息失败,身份证或手机号无效",
"error": "身份证或手机号无效",
})
}
// 如果身份正常,则返回所有信息
return c.JSON(result)
}
}
// Redis中 取数据
func getEKTPlatformToken(redisClient *redis.Storage, username string, password string) (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(username, password)
if err != nil {
return "", errors.New(err.Error())
}
redisClient.Set("testToken", []byte(token), 3600)
return token, nil
}
func fetchTokenFromAPI(username, password string) (string, error) {
//url 定义在config.go中
cfg := config.New()
url := cfg.APITokenUrl
reqBody := map[string]string{
"username": username,
"password": password,
}
reqBodyJson, _ := json.Marshal(reqBody)
returnValue, err := http.Post(url, "application/json", bytes.NewBuffer(reqBodyJson))
if err != nil {
return "", errors.New("获取token失败")
}
defer returnValue.Body.Close()
body, _ := io.ReadAll(returnValue.Body)
// 解析返回的json数据判断是否有code字段并且code是否为1如果是则获取并返回token
var result map[string]interface{}
json.Unmarshal(body, &result)
if _, ok := result["code"]; !ok || result["code"] != 1 {
return "", errors.New("fetchTokenFromAPI:获取token失败,token无效,code:"+result["code"]+" message:"+result["message"])
}
// 如果不存在message字段或message字段的值为空则token为空
if _, ok := result["message"]; !ok || result["message"] == "" {
return "", errors.New("获取token失败,token为空")
}
return result["message"].(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
}