diff --git a/im-platform/src/main/java/com/bx/implatform/dto/LoginDTO.java b/im-platform/src/main/java/com/bx/implatform/dto/LoginDTO.java index 30b240e..6440c65 100644 --- a/im-platform/src/main/java/com/bx/implatform/dto/LoginDTO.java +++ b/im-platform/src/main/java/com/bx/implatform/dto/LoginDTO.java @@ -25,4 +25,7 @@ public class LoginDTO { @Schema(description = "用户密码") private String password; + @Schema(description = "ip地址") + private String ip; + } diff --git a/im-platform/src/main/java/com/bx/implatform/entity/User.java b/im-platform/src/main/java/com/bx/implatform/entity/User.java index 6b43806..b34d948 100644 --- a/im-platform/src/main/java/com/bx/implatform/entity/User.java +++ b/im-platform/src/main/java/com/bx/implatform/entity/User.java @@ -94,4 +94,14 @@ public class User { */ private Integer isCustomer = 1; + /** + * 最后登录ip + */ + private String lastLoginIp; + + /** + * ip转换的地址 + */ + private String ipAddress; + } diff --git a/im-platform/src/main/java/com/bx/implatform/service/UserService.java b/im-platform/src/main/java/com/bx/implatform/service/UserService.java index 4319bb7..c46e5a3 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/UserService.java +++ b/im-platform/src/main/java/com/bx/implatform/service/UserService.java @@ -90,5 +90,12 @@ public interface UserService extends IService { */ List getOnlineTerminals(String userIds); + /** + * 记录ip与ip地址 + * + * @param user 用户 + */ + void updateIpAndAddress(User user); + } diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java index 1172c10..abba7f4 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java +++ b/im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.bx.imclient.IMClient; @@ -25,6 +26,7 @@ import com.bx.implatform.service.UserService; import com.bx.implatform.session.SessionContext; import com.bx.implatform.session.UserSession; import com.bx.implatform.util.BeanUtils; +import com.bx.implatform.util.IpUtils; import com.bx.implatform.util.SensitiveFilterUtil; import com.bx.implatform.vo.LoginVO; import com.bx.implatform.vo.OnlineTerminalVO; @@ -66,6 +68,10 @@ public class UserServiceImpl extends ServiceImpl implements Us if (!passwordEncoder.matches(dto.getPassword(), user.getPassword())) { throw new GlobalException(ResultCode.PASSWOR_ERROR); } + if(!Objects.isNull(dto.getIp())){ + user.setLastLoginIp(dto.getIp()); + this.updateIpAndAddress(user); + } // 生成token UserSession session = BeanUtils.copyProperties(user, UserSession.class); session.setUserId(user.getId()); @@ -259,4 +265,14 @@ public class UserServiceImpl extends ServiceImpl implements Us }); return vos; } + + @Override + public void updateIpAndAddress(User user) { + String ip = user.getLastLoginIp(); + String address = IpUtils.getIpAddress(ip); + this.update(new UpdateWrapper().lambda() + .eq(User::getId, user.getId()) + .set(User::getLastLoginIp, ip) + .set(User::getIpAddress, address)); + } } diff --git a/im-platform/src/main/java/com/bx/implatform/util/IpUtils.java b/im-platform/src/main/java/com/bx/implatform/util/IpUtils.java new file mode 100644 index 0000000..2c7cf5f --- /dev/null +++ b/im-platform/src/main/java/com/bx/implatform/util/IpUtils.java @@ -0,0 +1,75 @@ +package com.bx.implatform.util; + +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * IP 地址查询工具类 + * 使用 ipify 和 httpbin 获取 IP 地址的地理位置信息 + */ +@Slf4j +@Component +public class IpUtils { + + private static final String IP_API = "http://ip-api.com/json/"; + + + /** + * 根据 IP 地址查询地理位置 + * + * @param ip IP 地址 + * @return 地理位置信息,格式如:"中国广东省深圳市" + */ + public static String getIpAddress(String ip) { + System.out.println("333333333"); + System.out.println(ip); + + + if (ip == null || ip.trim().isEmpty() || "unknown".equalsIgnoreCase(ip)) { + return ""; + } + + try { + // 使用 ip-api.com 查询 IP 归属地 + String url = IP_API + ip; + String response = HttpUtil.get(url, 5000); + + System.out.println("2222222222222222"); + System.out.println( response); + + if (response != null && !response.isEmpty()) { + JSONObject json = JSON.parseObject(response); + String status = json.getString("status"); + + if ("success".equals(status)) { + String country = json.getString("country"); + String regionName = json.getString("regionName"); + String city = json.getString("city"); + + StringBuilder address = new StringBuilder(); + if (country != null && !country.isEmpty()) { + address.append(country); + } + if (regionName != null && !regionName.isEmpty() && !regionName.equals(country)) { + address.append(regionName); + } + if (city != null && !city.isEmpty() && !city.equals(regionName)) { + address.append(city); + } + + log.info("IP 地址查询成功:ip={}, address={}", ip, address); + return address.toString(); + } + } + } catch (Exception e) { + log.error("IP 地址查询失败:ip={}, error={}", ip, e.getMessage()); + } + + // 如果查询失败,返回空字符串 + return ""; + } + +} diff --git a/im-uniapp/pages/login/login.vue b/im-uniapp/pages/login/login.vue index ea2a6ca..9ae1be4 100644 --- a/im-uniapp/pages/login/login.vue +++ b/im-uniapp/pages/login/login.vue @@ -61,12 +61,13 @@ export default { dataForm: { terminal: 1, // APP终端 userName: '', - password: '' + password: '', + ip: '' } } }, methods: { - submit() { + async submit() { if (!this.dataForm.userName) { return uni.showToast({ title: "请输入您的账号", @@ -79,6 +80,11 @@ export default { icon: "none" }) } + + await this.getIp(); + + console.log("登录参数:", this.dataForm); + this.$http({ url: '/login', data: this.dataForm, @@ -101,6 +107,27 @@ export default { // 清理数据,防止缓存未失效 getApp().$vm.unloadStore(); }, + + async getIp() { + // 获取本机ip + return new Promise((resolve, reject) => { + uni.request({ + url: 'https://api.ipify.org?format=json', + method: 'GET', + success: (res) => { + console.log("获取IP成功:", res.data); + this.dataForm.ip = res.data.ip; + console.log("登录参数:", this.dataForm); + resolve(res.data.ip); // 成功时解析Promise + }, + fail: (err) => { + console.log("获取IP失败:", err); + reject(err); // 失败时拒绝Promise + } + }); + }); + }, + onSwitchShowPwd() { this.isShowPwd = !this.isShowPwd; },