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

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

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

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

(1)增加路由:

apiv1.POST("/history_login_logs", v1.AddHistoryLoginLog)

(2)在model里增加(例如:models/history_login_logs.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) 在登录后的方法中增加(需要引入

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")
 

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

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} />
    )
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值