react go实现用户历史登录列表页面

refer: http://ip-api.com/

1.首先需要创建一个保存用户历史的登录的表,然后连接go

2.在用户登录的时候,获取用户的IP IP位置,在后端直接处理数据即可(不需要在前端传递数据)

(1)增加路由:

Go 复制代码
apiv1.POST("/history_login_logs", v1.AddHistoryLoginLog)

(2)在model里增加(例如:models/history_login_logs.go)

Go 复制代码
 func AddHistoryLoginLog(user_id int, ip_address string, ip_location string, login_at time.Time) bool {
    db.Create(&HistoryLoginLogs{
      UserId:    user_id,
      IpAddress: ip_address,
      IpLocation:   ip_location,
      LoginAt: login_at,
    })

    return true
  }

(3) 在登录后的方法中增加(需要引入

Go 复制代码
import(
  "time"
  "io/ioutil"
  "fmt"
  "encoding/json"
)

type Location struct {
  Status      string  `json:"status"`
    Country     string  `json:"country"`
    CountryCode string  `json:"countryCode"`
    Region      string  `json:"region"`
    RegionName  string  `json:"regionName"`
    City        string  `json:"city"`
    Zip         string  `json:"zip"`
    Lat         float64 `json:"lat"`
    Lon         float64 `json:"lon"`
    Timezone    string  `json:"timezone"`
    Isp         string  `json:"isp"`
    Org         string  `json:"org"`
    As          string  `json:"as"`
    Query       string  `json:"query"`
}

...
ipAddress := c.ClientIP()
fmt.Println("== ip_address:", ipAddress)
resp, err := http.Get("http://ip-api.com/json/" + ipAddress + "?lang=zh-CN")
if err != nil {
  fmt.Println("Error:", err)
    return
}

defer resp.Body.Close()

  body, err := ioutil.ReadAll(resp.Body)
  if err != nil {
    fmt.Println("Error:", err)
      return
  }

  var location Location
err = json.Unmarshal(body, &location)
  if err != nil {
    fmt.Println("Error:", err)
      return
  }

fmt.Println("=== Location:", location)
City := location.City

  currentTime := time.Now()
models.AddHistoryLoginLog(user.ID, ipAddress, City, currentTime)
...

(4)增加action (例如:routers/api/v1/history_login_log.go)(需要引入import "net/http" "time" "fmt")

Go 复制代码
type AddHistoryLoginLogRequest struct {
    UserID     int    `json:"user_id" binding:"required"`
      IPAddress  string `json:"ip_address" binding:"required"`
      City string `json:"ip_location" binding:"required"`
      CurrentTime time.Time `json:"login_at" binding:"required"`
  }

func AddHistoryLoginLog(c *gin.Context) {
  var request AddHistoryLoginLogRequest
    if err := c.ShouldBindJSON(&request); err != nil {
      fmt.Println("== err: ", err)
        return
    }

  models.AddHistoryLoginLog(request.UserID, request.IPAddress, request.City, request.CurrentTime)

}

3.在前端写一个展示的列表页面即可。(登录时间写现在的时间即可。)

例如:src/pages/HistoryLoginLog/index.jsx

Go 复制代码
import React, { Component } from 'react'
import { Table } from 'antd';
import axios from 'axios'
import Config from '@/settings'
import { getToken, removeToken } from '@/utils/auth'

const columns = [
  {
    title: '登录名',
    dataIndex: 'user_id',
    key: 'user_id',
    render: text => <a>{text}</a>,
  },
  {
    title: '登陆时间',
    dataIndex: 'login_at',
    key: 'login_at',
    // 这里是进行时间的处理,转换为北京时间,格式为:2023/08/16 21:40
    render: text => {
      const dateObj = new Date(text);
      const localizedDate = dateObj.toLocaleString('zh-CN', {
        timeZone: 'Asia/Shanghai',
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
      });
      return <span>{localizedDate}</span>;
    },
  },
  {
    title: '登陆ip',
    dataIndex: 'ip_address',
    key: 'ip_address',
  },
  {
    title: '登陆位置',
    dataIndex: 'ip_location',
    key: 'ip_locatio',
  }
];

export default class CalculationPlan extends Component {
  state = {
    data: [],
    loading: true,
  }

  async fetchData() {
    try {
      const response = await axios.get(`${Config.BASE_URL}/api/v1/history_login_logs?token=${getToken()}`)
      if (response.data.message == "ok") {
        const sortedData = response.data.data.sort((a, b) => new Date(b.id) - new Date(a.id));
        this.setState({
          data: sortedData,
          loading: false,
        })
      }
    } catch (error) {
      console.error(error)
      removeToken()
      window.location.href = '/'
    }
  }

  componentDidMount() {
    this.fetchData()
  }

  render() {
    const { data, loading } = this.state

    return (
        <Table columns={columns} dataSource={data} loading={loading} />
    )
  }
}
相关推荐
酒鼎17 分钟前
学习笔记(12-02)事件循环 - 实战案例 —⭐
前端·javascript
Bigger22 分钟前
第一章:我是如何剖析 Claude Code 整体架构与启动流程的
前端·aigc·claude
竹林81828 分钟前
从“连接失败”到丝滑登录:我用 ethers.js v6 搞定 MetaMask 钱包连接的全过程
前端·javascript
oi..32 分钟前
《Web 安全入门|XSS 漏洞原理、CSP 策略与 HttpOnly 防护实践》
前端·网络·测试工具·安全·web安全·xss
UXbot41 分钟前
2026年AI全链路产品开发工具对比:5款从创意到上线一站式平台深度解析
前端·ui·kotlin·软件构建·swift·原型模式
一拳不是超人1 小时前
前端工程师也要懂的服务器部署知识:从 Nginx 到 CI/CD
服务器·前端
AlkaidSTART1 小时前
TanStack Query 技术指南:异步状态管理核心实践
前端·react.js
Tomhex1 小时前
Golang内置函数总结
golang·go
种花家的强总1 小时前
前端项目开发/维护中降低成本的方式之一:降低耦合度
前端
Palpitate_LL1 小时前
从XSS到“RCE“的PC端利用链构建
前端·xss