Merge remote-tracking branch 'origin/master'
# Conflicts:
# xp-api/src/main/java/com/xiaopeng/api/model/account/XpOperationsUser.java
# xp-api/src/main/java/com/xiaopeng/api/model/account/XpOperationsUserNotification.java
# xp-api/src/main/java/com/xiaopeng/api/model/maintenance/XpTask.java
# xp-api/src/main/java/com/xiaopeng/api/model/maintenance/XpVehicle.java
# xp-api/src/main/java/com/xiaopeng/api/model/operation/XpAgreementAppUser.java
# xp-api/src/main/java/com/xiaopeng/api/model/operation/XpElectronicFence.java
# xp-api/src/main/java/com/xiaopeng/api/model/operation/XpElectronicFenceArea.java
# xp-api/src/main/java/com/xiaopeng/api/model/operation/XpPoint.java
# xp-api/src/main/java/com/xiaopeng/api/model/operation/XpRegion.java
# xp-service/xp-account/src/main/java/com/xiaopeng/account/controller/TokenController.java
# xp-service/xp-account/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java
# xp-service/xp-account/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserNotificationMapper.java
# xp-service/xp-account/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserNotificationServiceImpl.java
# xp-service/xp-account/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
# xp-service/xp-account/src/main/resources/mapper/account/XpOperationsUserMapper.xml
# xp-service/xp-account/src/main/resources/mapper/account/XpOperationsUserNotificationMapper.xml
# xp-service/xp-maintenance/src/main/java/com/xiaopeng/maintenance/mapper/XpTaskMapper.java
# xp-service/xp-maintenance/src/main/java/com/xiaopeng/maintenance/mapper/XpVehicleMapper.java
# xp-service/xp-maintenance/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
# xp-service/xp-maintenance/src/main/java/com/xiaopeng/maintenance/service/impl/XpVehicleServiceImpl.java
# xp-service/xp-maintenance/src/main/resources/mapper/maintenance/XpTaskMapper.xml
# xp-service/xp-maintenance/src/main/resources/mapper/maintenance/XpVehicleMapper.xml
# xp-service/xp-operation/src/main/java/com/xiaopeng/operation/controller/XpPointController.java
# xp-service/xp-operation/src/main/java/com/xiaopeng/operation/controller/XpRegionController.java
# xp-service/xp-operation/src/main/java/com/xiaopeng/operation/mapper/XpPointMapper.java
# xp-service/xp-operation/src/main/java/com/xiaopeng/operation/mapper/XpRegionMapper.java
# xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/impl/XpPointServiceImpl.java
# xp-service/xp-operation/src/main/java/com/xiaopeng/operation/service/impl/XpRegionServiceImpl.java
# xp-service/xp-operation/src/main/resources/mapper/operation/XpPointMapper.xml
# xp-service/xp-operation/src/main/resources/mapper/operation/XpRegionMapper.xml
2个文件已删除
2 文件已重命名
39个文件已添加
48个文件已修改
| | |
| | | <parent> |
| | | <groupId>com.xiaopeng.logan</groupId> |
| | | <artifactId>logan-parent</artifactId> |
| | | <version>2.2.0</version> |
| | | <version>2.3.5</version> |
| | | </parent> |
| | | |
| | | <properties> |
| New file |
| | |
| | | package com.xiaopeng.api.dto.operation; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | @ApiModel(value = "运维APP验证码登录DTO") |
| | | public class AppLoginCodeDTO implements Serializable { |
| | | @ApiModelProperty(value = "账号") |
| | | private String phoneNumber; |
| | | @ApiModelProperty(value = "验证码") |
| | | private String verificationCode; |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.api.dto.operation; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | @ApiModel(value = "运维APP获取协议DTO") |
| | | public class AppLoginGetAgreementByTypeDTO implements Serializable { |
| | | @ApiModelProperty(value = "类型 1=用户服务协议 2=平台隐私政策 3=敏感个人信息处理情况说明 4=向第三方提供个人信息情况的说明 5=乘车须知 6=计费规则说明") |
| | | private Integer contentType; |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.api.dto.operation; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | @ApiModel(value = "运维APP获取手机验证码DTO") |
| | | public class AppLoginGetCodeDTO implements Serializable { |
| | | @ApiModelProperty(value = "账号", required = true) |
| | | private String phoneNumber; |
| | | @ApiModelProperty(value = "验证码类型 1登录 2忘记密码 3修改密码", required = true) |
| | | private Integer codeType; |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.api.dto.operation; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | @ApiModel(value = "运维APP账号密码登录DTO") |
| | | public class AppLoginPasswordDTO implements Serializable { |
| | | @ApiModelProperty(value = "账号") |
| | | private String phoneNumber; |
| | | @ApiModelProperty(value = "密码") |
| | | private String password; |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.api.dto.operation; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | @ApiModel(value = "运维APP修改密码DTO") |
| | | public class UpdatePasswordDTO implements Serializable { |
| | | @ApiModelProperty(value = "账号",required = true) |
| | | private String phoneNumber; |
| | | @ApiModelProperty(value = "验证码",required = true) |
| | | private String verificationCode; |
| | | @ApiModelProperty(value = "新密码",required = true) |
| | | private String newPassword; |
| | | @ApiModelProperty(value = "确认密码",required = true) |
| | | private String confirmPassword; |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.api.factory.operation; |
| | | |
| | | import com.xiaopeng.api.feignClient.operation.SysLogClient; |
| | | import com.xiaopeng.api.model.operation.SysOperLog; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.cloud.openfeign.FallbackFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | @Slf4j |
| | | @Component |
| | | public class SysLogClientFallbackFactory implements FallbackFactory<SysLogClient> { |
| | | @Override |
| | | public SysLogClient create(Throwable cause) { |
| | | return new SysLogClient(){ |
| | | |
| | | @Override |
| | | public R saveLog(SysOperLog sysOperLog) { |
| | | log.error("保存系统日志记录失败:{}", cause.getMessage()); |
| | | return R.fail("保存系统日志记录失败"); |
| | | } |
| | | }; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.api.feignClient.operation; |
| | | |
| | | import com.xiaopeng.api.factory.operation.SysLogClientFallbackFactory; |
| | | import com.xiaopeng.api.model.operation.SysOperLog; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum; |
| | | import org.springframework.cloud.openfeign.FeignClient; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | |
| | | @FeignClient(contextId = "SysLogClient", value = ServiceNameConstantsEnum.XP_OPERATION_SERVICE, fallbackFactory = SysLogClientFallbackFactory.class) |
| | | public interface SysLogClient { |
| | | |
| | | |
| | | /** |
| | | * 保存系统日志 |
| | | * @param sysOperLog |
| | | */ |
| | | @PostMapping("/operlog/saveLog") |
| | | R saveLog(SysOperLog sysOperLog); |
| | | } |
| | |
| | | package com.xiaopeng.api.model.operation; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import java.io.Serializable; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.experimental.Accessors; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * <p> |
| | | * 省市区三级联动 |
| | | * 省市管理 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2026-02-03 |
| | | * @author xiaochen |
| | | * @since 2024-02-29 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = false) |
| | | @Accessors(chain = true) |
| | | @TableName("xp_region") |
| | | @ApiModel(value="XpRegion对象", description="省市区三级联动") |
| | | @ApiModel(value="TRegion对象", description="省市管理") |
| | | public class XpRegion implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @ApiModelProperty(value = "主键ID") |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Integer id; |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "城市名称") |
| | | @TableField("name") |
| | | private String name; |
| | | |
| | | @ApiModelProperty(value = "城市代码") |
| | | @TableField("code") |
| | | private String code; |
| | | |
| | | private String citycode; |
| | | @ApiModelProperty(value = "城市code") |
| | | @TableField("cityCode") |
| | | private String cityCode; |
| | | |
| | | @ApiModelProperty(value = "父级ID") |
| | | private Integer parentId; |
| | | @TableField("parentId") |
| | | private Long parentId; |
| | | |
| | | @ApiModelProperty(value = "英文名称") |
| | | @TableField("english") |
| | | private String english; |
| | | |
| | | @ApiModelProperty(value = "首字母") |
| | | @TableField("initial") |
| | | private String initial; |
| | | |
| | | private String lat; |
| | | |
| | | private String lon; |
| | | |
| | | private String lat; |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.api.vo.account; |
| | | |
| | | |
| | | import com.xiaopeng.api.model.account.SysRole; |
| | | import com.xiaopeng.api.model.account.SysUser; |
| | | import com.xiaopeng.api.model.account.XpOperationsUser; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * 运维用户信息 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class LoginOperationUser implements Serializable |
| | | { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 用户唯一标识 |
| | | */ |
| | | private String token; |
| | | |
| | | /** |
| | | * 用户名id |
| | | */ |
| | | private Long id; |
| | | |
| | | /** |
| | | * 用户名 |
| | | */ |
| | | private String username; |
| | | |
| | | /** |
| | | * 登录时间 |
| | | */ |
| | | private Long loginTime; |
| | | |
| | | /** |
| | | * 过期时间 |
| | | */ |
| | | private Long expireTime; |
| | | |
| | | /** |
| | | * 登录IP地址 |
| | | */ |
| | | private String ipaddr; |
| | | |
| | | /** |
| | | * 权限列表 |
| | | */ |
| | | private Set<String> permissions; |
| | | |
| | | /** |
| | | * 角色列表 |
| | | */ |
| | | private Set<String> roles; |
| | | |
| | | |
| | | |
| | | /** |
| | | * 用户信息 |
| | | */ |
| | | private XpOperationsUser xpOperationsUser; |
| | | /** |
| | | * 用户类型(系统用户,小程序用户) |
| | | */ |
| | | private String userType; |
| | | |
| | | public String getToken() |
| | | { |
| | | return token; |
| | | } |
| | | |
| | | public void setToken(String token) |
| | | { |
| | | this.token = token; |
| | | } |
| | | |
| | | public Long getId() |
| | | { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(Long id) |
| | | { |
| | | this.id = id; |
| | | } |
| | | |
| | | public String getUsername() |
| | | { |
| | | return username; |
| | | } |
| | | |
| | | public void setUsername(String username) |
| | | { |
| | | this.username = username; |
| | | } |
| | | |
| | | public Long getLoginTime() |
| | | { |
| | | return loginTime; |
| | | } |
| | | |
| | | public void setLoginTime(Long loginTime) |
| | | { |
| | | this.loginTime = loginTime; |
| | | } |
| | | |
| | | public Long getExpireTime() |
| | | { |
| | | return expireTime; |
| | | } |
| | | |
| | | public void setExpireTime(Long expireTime) |
| | | { |
| | | this.expireTime = expireTime; |
| | | } |
| | | |
| | | public String getIpaddr() |
| | | { |
| | | return ipaddr; |
| | | } |
| | | |
| | | public void setIpaddr(String ipaddr) |
| | | { |
| | | this.ipaddr = ipaddr; |
| | | } |
| | | |
| | | public Set<String> getPermissions() |
| | | { |
| | | return permissions; |
| | | } |
| | | |
| | | public void setPermissions(Set<String> permissions) |
| | | { |
| | | this.permissions = permissions; |
| | | } |
| | | |
| | | public Set<String> getRoles() |
| | | { |
| | | return roles; |
| | | } |
| | | |
| | | public void setRoles(Set<String> roles) |
| | | { |
| | | this.roles = roles; |
| | | } |
| | | |
| | | public XpOperationsUser getXpOperationsUser() |
| | | { |
| | | return xpOperationsUser; |
| | | } |
| | | |
| | | public void setXpOperationsUser(XpOperationsUser xpOperationsUser) |
| | | { |
| | | this.xpOperationsUser = xpOperationsUser; |
| | | } |
| | | |
| | | public String getUserType() { |
| | | return userType; |
| | | } |
| | | |
| | | public void setUserType(String userType) { |
| | | this.userType = userType; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.api.vo.operation; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Data |
| | | @ApiModel("电子围栏开放区域Vo") |
| | | public class XpElectronicFenceVo { |
| | | @ApiModelProperty(value = "id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "围栏名称") |
| | | private String name; |
| | | |
| | | @ApiModelProperty(value = "多边形顶点坐标数组") |
| | | private List<XpPointsVo> points; |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.api.vo.operation; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | @ApiModel("经纬度信息Vo") |
| | | public class XpPointsVo { |
| | | private Double lat; |
| | | |
| | | private Double lng; |
| | | } |
| | |
| | | com.xiaopeng.api.factory.operation.SysLogClientFallbackFactory |
| | |
| | | /** |
| | | * 用户ID字段 |
| | | */ |
| | | public static final String DETAILS_USER_ID = "user_id"; |
| | | public static final String DETAILS_USER_ID = "id"; |
| | | |
| | | /** |
| | | * 用户名字段 |
| | |
| | | * 用户标识 |
| | | */ |
| | | public static final String USER_KEY = "user_key"; |
| | | |
| | | /** |
| | | * 运维人员用户表示 |
| | | */ |
| | | public static final String OPERATION_USER_KEY = "operation_user_key"; |
| | | |
| | | /** |
| | | * 用户类型(system/applet) |
| | | */ |
| | |
| | | /** |
| | | * 密码长度限制 |
| | | */ |
| | | public static final int PASSWORD_MIN_LENGTH = 5; |
| | | public static final int PASSWORD_MIN_LENGTH = 11; |
| | | |
| | | public static final int PASSWORD_MAX_LENGTH = 40; |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.common.core.constant; |
| | | |
| | | /** |
| | | * 验证码类型常量信息 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class VerificationCodeConstants |
| | | { |
| | | /** 是否为系统默认(是) */ |
| | | public static final String LOGIN_CODE = "loginCode_"; |
| | | |
| | | /** 是否菜单外链(是) */ |
| | | public static final String FORGET_PASSWORD_CODE= "forgetPasswordCode_"; |
| | | |
| | | /** 是否菜单外链(否) */ |
| | | public static final String UPDATE_PASSWORD_CODE = "updatePasswordCode_"; |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.common.core.dto; |
| | | |
| | | |
| | | /** |
| | | * 服务名称常量枚举类 |
| | | */ |
| | | public interface ServiceNameConstantsEnum { |
| | | /** |
| | | * 账户服务 |
| | | */ |
| | | String XP_ACCOUNT_SERVICE = "xp-account"; |
| | | /** |
| | | * 自动驾驶服务 |
| | | */ |
| | | String XP_AUTOMATIC_PILOT_SERVICE = "xp-automaticPilot"; |
| | | /** |
| | | * 行程服务 |
| | | */ |
| | | String XP_ITINERARY_SERVICE = "xp-itinerary"; |
| | | /** |
| | | * 运维服务 |
| | | */ |
| | | String XP_MAINTENANCE_SERVICE = "xp-maintenance"; |
| | | /** |
| | | * 地图服务 |
| | | */ |
| | | String XP_MAP_SERVICE = "xp-map"; |
| | | /** |
| | | * 运营服务 |
| | | */ |
| | | String XP_OPERATION_SERVICE = "xp-operation"; |
| | | /** |
| | | * 订单服务 |
| | | */ |
| | | String XP_ORDER_SERVICE = "xp-order"; |
| | | /** |
| | | * 支付服务 |
| | | */ |
| | | String XP_PAYMENT_SERVICE = "xp-payment"; |
| | | /** |
| | | * 推送服务 |
| | | */ |
| | | String XP_PUSH_MESSAGE_SERVICE = "xp-pushMessage"; |
| | | /** |
| | | * 远程驾驶服务 |
| | | */ |
| | | String XP_REMOTE_DRIVING_SERVICE = "xp-remoteDriving"; |
| | | /** |
| | | * 车辆车队服务 |
| | | */ |
| | | String XP_VEHICLE_CONVOY_SERVICE = "xp-vehicleConvoy"; |
| | | |
| | | } |
| | |
| | | Claims claims = parseToken(token); |
| | | return getValue(claims, SecurityConstants.USER_KEY); |
| | | } |
| | | /** |
| | | * 根据令牌获取运维用户标识 |
| | | * |
| | | * @param token 令牌 |
| | | * @return 用户ID |
| | | */ |
| | | public static String getOperationUserKey(String token) |
| | | { |
| | | Claims claims = parseToken(token); |
| | | return getValue(claims, SecurityConstants.OPERATION_USER_KEY); |
| | | } |
| | | |
| | | /** |
| | | * 根据令牌获取用户标识 |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | import com.xiaopeng.api.model.account.SysRole; |
| | | import com.xiaopeng.api.model.account.SysUser; |
| | | import com.xiaopeng.api.vo.account.LoginUser; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | |
| | | import com.xiaopeng.common.core.web.domain.BaseEntity; |
| | | import com.xiaopeng.common.datascope.annotation.DataScope; |
| | | import com.xiaopeng.common.security.utils.SecurityUtils; |
| | | import com.ruoyi.system.api.domain.SysRole; |
| | | import com.ruoyi.system.api.domain.SysUser; |
| | | |
| | | /** |
| | | * 数据过滤处理 |
| | |
| | | package com.xiaopeng.common.log.service; |
| | | |
| | | import com.xiaopeng.api.feignClient.operation.SysLogClient; |
| | | import com.xiaopeng.api.model.operation.SysOperLog; |
| | | import org.springframework.scheduling.annotation.Async; |
| | | import org.springframework.stereotype.Service; |
| | | import com.xiaopeng.common.core.constant.SecurityConstants; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | |
| | | */ |
| | | @Service |
| | | public class AsyncLogService { |
| | | |
| | | @Resource |
| | | private RemoteLogService remoteLogService; |
| | | private SysLogClient sysLogClient; |
| | | |
| | | /** |
| | | * 保存系统日志记录 |
| | | */ |
| | | @Async |
| | | public void saveSysLog(SysOperLog sysOperLog) throws Exception { |
| | | remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER); |
| | | sysLogClient.saveLog(sysOperLog); |
| | | } |
| | | } |
| | |
| | | // 表示通过aop框架暴露该代理对象,AopContext能够访问 |
| | | @EnableAspectJAutoProxy(exposeProxy = true) |
| | | // 指定要扫描的Mapper类的包的路径 |
| | | @MapperScan("com.ruoyi.**.mapper") |
| | | @MapperScan("com.xiaopeng.**.mapper") |
| | | // 开启线程异步执行 |
| | | @EnableAsync |
| | | // 自动加载类 |
| | |
| | | { |
| | | String[] value() default {}; |
| | | |
| | | String[] basePackages() default { "com.ruoyi" }; |
| | | String[] basePackages() default { "com.xiaopeng" }; |
| | | |
| | | Class<?>[] basePackageClasses() default {}; |
| | | |
| | |
| | | /** |
| | | * 定义AOP签名 (切入所有使用鉴权注解的方法) |
| | | */ |
| | | public static final String POINTCUT_SIGN = " @annotation(com.ruoyi.common.security.annotation.RequiresLogin) || " |
| | | + "@annotation(com.ruoyi.common.security.annotation.RequiresPermissions) || " |
| | | + "@annotation(com.ruoyi.common.security.annotation.RequiresRoles)"; |
| | | public static final String POINTCUT_SIGN = " @annotation(com.xiaopeng.common.security.annotation.RequiresLogin) || " |
| | | + "@annotation(com.xiaopeng.common.security.annotation.RequiresPermissions) || " |
| | | + "@annotation(com.xiaopeng.common.security.annotation.RequiresRoles)"; |
| | | |
| | | /** |
| | | * 声明AOP签名 |
| | |
| | | import java.util.concurrent.TimeUnit; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | | import com.xiaopeng.api.vo.account.LoginOperationUser; |
| | | import com.xiaopeng.common.core.exception.auth.NotLoginException; |
| | | import com.xiaopeng.api.vo.account.LoginUser; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | rspMap.put("expires_in", expireTime); |
| | | return rspMap; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 运维人员创建令牌 |
| | | * @param userInfo |
| | | * @return |
| | | */ |
| | | public Map<String, Object> createOperationUserToken(LoginOperationUser userInfo) { |
| | | String token = IdUtils.fastUUID(); |
| | | Long userId = userInfo.getXpOperationsUser().getId(); |
| | | String userName = userInfo.getXpOperationsUser().getPhoneNumber(); |
| | | userInfo.setToken(token); |
| | | userInfo.setId(userId); |
| | | userInfo.setUsername(userName); |
| | | userInfo.setIpaddr(IpUtils.getIpAddr()); |
| | | refreshTokenOperationUser(userInfo); |
| | | |
| | | // Jwt存储信息 |
| | | Map<String, Object> claimsMap = new HashMap<String, Object>(); |
| | | claimsMap.put(SecurityConstants.OPERATION_USER_KEY, token); |
| | | claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId); |
| | | claimsMap.put(SecurityConstants.USER_TYPE, "operation"); |
| | | claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName); |
| | | // 接口返回信息 |
| | | Map<String, Object> rspMap = new HashMap<String, Object>(); |
| | | rspMap.put("access_token", JwtUtils.createToken(claimsMap)); |
| | | rspMap.put("expires_in", expireTime); |
| | | return rspMap; |
| | | } |
| | | /** |
| | | * 获取用户身份信息 |
| | | * |
| | |
| | | } |
| | | return loginUser; |
| | | } |
| | | |
| | | /** |
| | | * 获取运维人员登录信息 |
| | | * |
| | | * @return 用户信息 |
| | | */ |
| | | public LoginOperationUser getLoginOperationUser() { |
| | | LoginOperationUser loginUser = getLoginOperationUser(ServletUtils.getRequest()); |
| | | if (loginUser == null) { |
| | | throw new NotLoginException("令牌已过期,请重新登录!"); |
| | | } |
| | | return loginUser; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取用户身份信息 |
| | | * |
| | |
| | | // 获取请求携带的令牌 |
| | | String token = SecurityUtils.getToken(request); |
| | | return getLoginUser(token); |
| | | } |
| | | /** |
| | | * 获取用户身份信息 |
| | | * |
| | | * @return 用户信息 |
| | | */ |
| | | public LoginOperationUser getLoginOperationUser(HttpServletRequest request) { |
| | | // 获取请求携带的令牌 |
| | | String token = SecurityUtils.getToken(request); |
| | | return getLoginOperationUser(token); |
| | | } |
| | | |
| | | /** |
| | |
| | | try { |
| | | if (StringUtils.isNotEmpty(token)) { |
| | | String userkey = JwtUtils.getUserKey(token); |
| | | user = redisService.getCacheObject(getTokenKey(userkey)); |
| | | return user; |
| | | } |
| | | } catch (Exception e) { |
| | | } |
| | | return user; |
| | | } |
| | | /** |
| | | * 获取运维用户身份信息 |
| | | * |
| | | * @return 用户信息 |
| | | */ |
| | | public LoginOperationUser getLoginOperationUser(String token) { |
| | | LoginOperationUser user = null; |
| | | try { |
| | | if (StringUtils.isNotEmpty(token)) { |
| | | String userkey = JwtUtils.getOperationUserKey(token); |
| | | user = redisService.getCacheObject(getTokenKey(userkey)); |
| | | return user; |
| | | } |
| | |
| | | String tokenKey = getTokenKey(loginUser.getToken()); |
| | | redisService.setCacheObject(tokenKey, loginUser, expireTime, TimeUnit.MINUTES); |
| | | } |
| | | /** |
| | | * 刷新运维APP端令牌有效期 |
| | | * |
| | | * @param loginUser 登录信息 |
| | | */ |
| | | public void refreshTokenOperationUser(LoginOperationUser loginUser) { |
| | | loginUser.setLoginTime(System.currentTimeMillis()); |
| | | loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); |
| | | // 根据uuid将loginUser缓存 |
| | | String tokenKey = getTokenKey(loginUser.getToken()); |
| | | redisService.setCacheObject(tokenKey, loginUser, expireTime, TimeUnit.MINUTES); |
| | | } |
| | | |
| | | private String getTokenKey(String token) { |
| | | return ACCESS_TOKEN + token; |
| New file |
| | |
| | | package com.xiaopeng.gateway; |
| | | |
| | | import org.springframework.boot.SpringApplication; |
| | | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| | | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; |
| | | |
| | | /** |
| | | * 网关启动程序 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) |
| | | public class GatewayApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(GatewayApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 网关启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | |
| | | } |
| | |
| | | // KAPTCHA_SESSION_KEY |
| | | properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); |
| | | // 验证码文本生成器 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.gateway.config.KaptchaTextCreator"); |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.xiaopeng.gateway.config.KaptchaTextCreator"); |
| | | // 验证码文本字符间距 默认为2 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); |
| | | // 验证码文本字符长度 默认为5 |
| | |
| | | </appender> |
| | | |
| | | <!-- 系统模块日志级别控制 --> |
| | | <logger name="com.ruoyi" level="info" /> |
| | | <logger name="com.xiaopeng" level="info" /> |
| | | <!-- Spring日志级别控制 --> |
| | | <logger name="org.springframework" level="warn" /> |
| | | |
| | |
| | | </appender> |
| | | |
| | | <!-- 系统模块日志级别控制 --> |
| | | <logger name="com.ruoyi" level="info" /> |
| | | <logger name="com.xiaopeng" level="info" /> |
| | | <!-- Spring日志级别控制 --> |
| | | <logger name="org.springframework" level="warn" /> |
| | | |
| | |
| | | public class AccountApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(AccountApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 账户模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 账户模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | | import com.xiaopeng.account.service.ISysUserService; |
| | | import com.xiaopeng.account.service.SysLoginService; |
| | | import com.xiaopeng.account.service.XpOperationsUserService; |
| | | import com.xiaopeng.account.service.impl.SysLoginService; |
| | | import com.xiaopeng.account.vo.LoginBody; |
| | | import com.xiaopeng.account.vo.RegisterBody; |
| | | import com.xiaopeng.api.dto.operation.AppLoginCodeDTO; |
| | | import com.xiaopeng.api.dto.operation.AppLoginGetCodeDTO; |
| | | import com.xiaopeng.api.dto.operation.AppLoginPasswordDTO; |
| | | import com.xiaopeng.api.dto.operation.UpdatePasswordDTO; |
| | | import com.xiaopeng.api.model.account.SysRole; |
| | | import com.xiaopeng.api.model.account.SysRoleBak; |
| | | import com.xiaopeng.api.model.account.SysUser; |
| | | import com.xiaopeng.api.model.account.XpOperationsUser; |
| | | import com.xiaopeng.api.vo.account.LoginOperationUser; |
| | | import com.xiaopeng.api.vo.account.LoginUser; |
| | | import com.xiaopeng.common.core.constant.VerificationCodeConstants; |
| | | import com.xiaopeng.common.redis.service.RedisService; |
| | | import io.seata.spring.annotation.GlobalTransactional; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | import com.xiaopeng.common.security.utils.SecurityUtils; |
| | | |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * token 控制 |
| | |
| | | */ |
| | | @Slf4j |
| | | @RestController |
| | | @RequestMapping("/base/v1") |
| | | public class TokenController { |
| | | @Autowired |
| | | private TokenService tokenService; |
| | |
| | | |
| | | @Resource |
| | | private ISysUserService sysUserService; |
| | | |
| | | |
| | | |
| | | |
| | | @ApiOperation(value = "用户登录", tags = "管理后台-用户登录") |
| | | @PostMapping("/login") |
| | | @GlobalTransactional(rollbackFor = Exception.class)//分布式事务 |
| | | public R<?> login(@RequestBody LoginBody form, HttpServletRequest request) { |
| | | // 用户登录 |
| | | LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword(), request); |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | map.put("token", tokenService.createToken(userInfo)); |
| | | List<SysRole> roles = userInfo.getSysUser().getRoles(); |
| | | if(CollectionUtils.isEmpty(roles)){ |
| | | @Resource |
| | | private XpOperationsUserService xpOperationsUserService; |
| | | |
| | | @Autowired |
| | | private RedisService redisService; |
| | | |
| | | @ApiOperation(value = "用户登录", tags = "管理后台-用户登录") |
| | | @PostMapping("login") |
| | | @GlobalTransactional(rollbackFor = Exception.class)//分布式事务 |
| | | public R<?> login(@RequestBody LoginBody form, HttpServletRequest request) { |
| | | // 用户登录 |
| | | LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword(), request); |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | map.put("token", tokenService.createToken(userInfo)); |
| | | List<SysRole> roles = userInfo.getSysUser().getRoles(); |
| | | if (CollectionUtils.isEmpty(roles)) { |
| | | return R.fail("请关联角色!"); |
| | | } |
| | | map.put("roleName",roles.get(0).getRoleName()); |
| | |
| | | SysUser sysUser = new SysUser(); |
| | | sysUser.setId(userInfo.getSysUser().getId()); |
| | | sysUserService.updateById(sysUser); |
| | | return R.ok(map); |
| | | } |
| | | |
| | | @DeleteMapping("logout") |
| | | public R<?> logout(HttpServletRequest request) { |
| | | String token = SecurityUtils.getToken(request); |
| | | if (StringUtils.isNotEmpty(token)) { |
| | | String username = JwtUtils.getUserName(token); |
| | | // 删除用户缓存记录 |
| | | AuthUtil.logoutByToken(token); |
| | | // 记录用户退出日志 |
| | | sysLoginService.logout(username, request); |
| | | return R.ok(map); |
| | | } |
| | | |
| | | @ApiOperation(value = "账号密码登录", tags = {"运维APP登录"}) |
| | | @PostMapping("base/v1/operationPasswordLogin") |
| | | @GlobalTransactional(rollbackFor = Exception.class)//分布式事务 |
| | | public R<?> operationPasswordLogin(@RequestBody AppLoginPasswordDTO appLoginPasswordDTO, HttpServletRequest request) { |
| | | // 用户登录 |
| | | LoginOperationUser userInfo = sysLoginService.operationPasswordLogin(appLoginPasswordDTO.getPhoneNumber(), appLoginPasswordDTO.getPassword(), request); |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | map.put("token", tokenService.createOperationUserToken(userInfo)); |
| | | List<SysRole> roles = userInfo.getXpOperationsUser().getRoles(); |
| | | if (CollectionUtils.isEmpty(roles)) { |
| | | return R.fail("请关联角色!"); |
| | | } |
| | | map.put("roleName", roles.get(0).getRoleName()); |
| | | map.put("info", userInfo); |
| | | return R.ok(map); |
| | | } |
| | | |
| | | @ApiOperation(value = "手机验证码登录", tags = {"运维APP登录"}) |
| | | @PostMapping("base/v1/verificationCodeLogin") |
| | | @GlobalTransactional(rollbackFor = Exception.class)//分布式事务 |
| | | public R<?> verificationCodeLogin(@RequestBody AppLoginCodeDTO appLoginCodeDTO, HttpServletRequest request) { |
| | | // 用户登录 |
| | | LoginOperationUser userInfo = sysLoginService.verificationCodeLogin(appLoginCodeDTO.getPhoneNumber(), appLoginCodeDTO.getVerificationCode(), request); |
| | | HashMap<String, Object> map = new HashMap<>(); |
| | | map.put("token", tokenService.createOperationUserToken(userInfo)); |
| | | List<SysRole> roles = userInfo.getXpOperationsUser().getRoles(); |
| | | if (CollectionUtils.isEmpty(roles)) { |
| | | return R.fail("请关联角色!"); |
| | | } |
| | | map.put("roleName", roles.get(0).getRoleName()); |
| | | map.put("info", userInfo); |
| | | return R.ok(map); |
| | | } |
| | | |
| | | @ApiOperation(value = "获取手机验证码", tags = {"运维APP登录"}) |
| | | @PostMapping("base/v1/getVerificationCode") |
| | | @GlobalTransactional(rollbackFor = Exception.class)//分布式事务 |
| | | public R<?> verificationCodeLogin(@RequestBody AppLoginGetCodeDTO appLoginPasswordDTO) { |
| | | XpOperationsUser xpOperationsUser = xpOperationsUserService.lambdaQuery() |
| | | .eq(XpOperationsUser::getPhoneNumber, appLoginPasswordDTO.getPhoneNumber()) |
| | | .last("limit 1").one(); |
| | | if (xpOperationsUser == null) { |
| | | return R.fail("账号不存在!"); |
| | | } |
| | | if (!xpOperationsUser.getStatus()) { |
| | | return R.fail("账号已禁用!"); |
| | | } |
| | | // todo 后续补充验证码 |
| | | // 生成6位数短信验证码 |
| | | String code = String.valueOf((int) (Math.random() * 1000000)); |
| | | String codeType = ""; |
| | | switch (appLoginPasswordDTO.getCodeType()) { |
| | | case 1: |
| | | codeType = VerificationCodeConstants.LOGIN_CODE; |
| | | break; |
| | | case 2: |
| | | codeType = VerificationCodeConstants.FORGET_PASSWORD_CODE; |
| | | |
| | | break; |
| | | case 3: |
| | | codeType = VerificationCodeConstants.UPDATE_PASSWORD_CODE; |
| | | |
| | | break; |
| | | } |
| | | redisService.setCacheObject(codeType+appLoginPasswordDTO.getPhoneNumber(), code, 60L, TimeUnit.SECONDS); |
| | | return R.ok(); |
| | | } |
| | | @ApiOperation(value = "修改密码", tags = {"运维APP登录"}) |
| | | @PostMapping("base/v1/updatePassword") |
| | | @GlobalTransactional(rollbackFor = Exception.class)//分布式事务 |
| | | public R<?> updatePassword(@RequestBody UpdatePasswordDTO updatePasswordDTO, HttpServletRequest request) { |
| | | // 用户登录 |
| | | if (sysLoginService.verificationCodeUpdate(updatePasswordDTO, request)){ |
| | | return R.ok("修改成功,请重新登录"); |
| | | }else{ |
| | | return R.fail("修改失败"); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | |
| | | @PostMapping("refresh") |
| | | public R<?> refresh(HttpServletRequest request) { |
| | | LoginUser loginUser = tokenService.getLoginUser(request); |
| | | if (StringUtils.isNotNull(loginUser)) { |
| | | // 刷新令牌有效期 |
| | | tokenService.refreshToken(loginUser); |
| | | return R.ok(); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @PostMapping("register") |
| | | public R<?> register(@RequestBody RegisterBody registerBody, HttpServletRequest request) { |
| | | // 用户注册 |
| | | sysLoginService.register(registerBody.getUsername(), registerBody.getPassword(), request); |
| | | return R.ok(); |
| | | } |
| | | |
| | | |
| | | @DeleteMapping("logout") |
| | | public R<?> logout(HttpServletRequest request) { |
| | | String token = SecurityUtils.getToken(request); |
| | | if (StringUtils.isNotEmpty(token)) { |
| | | String username = JwtUtils.getUserName(token); |
| | | // 删除用户缓存记录 |
| | | AuthUtil.logoutByToken(token); |
| | | // 记录用户退出日志 |
| | | sysLoginService.logout(username, request); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | |
| | | @PostMapping("refresh") |
| | | public R<?> refresh(HttpServletRequest request) { |
| | | LoginUser loginUser = tokenService.getLoginUser(request); |
| | | if (StringUtils.isNotNull(loginUser)) { |
| | | // 刷新令牌有效期 |
| | | tokenService.refreshToken(loginUser); |
| | | return R.ok(); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @PostMapping("register") |
| | | public R<?> register(@RequestBody RegisterBody registerBody, HttpServletRequest request) { |
| | | // 用户注册 |
| | | sysLoginService.register(registerBody.getUsername(), registerBody.getPassword(), request); |
| | | return R.ok(); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.account.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xiaopeng.api.model.account.XpOperationsUserNotification; |
| | | |
| | | /** |
| | | * <p> |
| | | * 运维人员消息通知表 服务类 |
| | | * </p> |
| | | * |
| | | * @author WuGuanFengYue |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpOperationsUserNotificationService extends IService<XpOperationsUserNotification> { |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.account.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xiaopeng.api.model.account.XpOperationsUser; |
| | | |
| | | /** |
| | | * <p> |
| | | * 运维人员 服务类 |
| | | * </p> |
| | | * |
| | | * @author WuGuanFengYue |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpOperationsUserService extends IService<XpOperationsUser> { |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.account.service.impl; |
| | | |
| | | import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ; |
| | | import com.xiaopeng.api.dto.operation.UpdatePasswordDTO; |
| | | import com.xiaopeng.account.service.ISysPermissionService; |
| | | import com.xiaopeng.account.service.ISysUserService; |
| | | import com.xiaopeng.api.model.account.SysUser; |
| | | import com.xiaopeng.api.model.account.XpOperationsUser; |
| | | import com.xiaopeng.api.vo.account.LoginOperationUser; |
| | | import com.xiaopeng.api.model.operation.SysMenu; |
| | | import com.xiaopeng.api.vo.account.LoginUser; |
| | | import com.xiaopeng.common.core.constant.VerificationCodeConstants; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import com.xiaopeng.common.core.constant.CacheConstants; |
| | | import com.xiaopeng.common.core.constant.Constants; |
| | | import com.xiaopeng.common.core.constant.UserConstants; |
| | | import com.xiaopeng.common.core.enums.UserStatus; |
| | | import com.xiaopeng.common.core.exception.ServiceException; |
| | | import com.xiaopeng.common.core.text.Convert; |
| | | import com.xiaopeng.common.core.utils.StringUtils; |
| | | import com.xiaopeng.common.core.utils.ip.IpUtils; |
| | | import com.xiaopeng.common.redis.service.RedisService; |
| | | import com.xiaopeng.common.security.utils.SecurityUtils; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * 登录校验方法 |
| | | * |
| | | * @author xiaopeng |
| | | */ |
| | | @Component |
| | | public class SysLoginService { |
| | | |
| | | @Autowired |
| | | private SysPasswordService passwordService; |
| | | |
| | | @Autowired |
| | | private SysRecordLogService recordLogService; |
| | | |
| | | @Autowired |
| | | private RedisService redisService; |
| | | |
| | | @Resource |
| | | private ISysPermissionService permissionService; |
| | | |
| | | @Resource |
| | | private ISysUserService userService; |
| | | @Resource |
| | | private XpOperationsUserService operationsUserService; |
| | | |
| | | |
| | | /** |
| | | * 登录 |
| | | */ |
| | | public LoginUser login(String username, String password, HttpServletRequest request) { |
| | | username = username.trim(); |
| | | // 查询用户信息 |
| | | SysUser user = userService.selectUserByUserName(username); |
| | | if (StringUtils.isNull(user)) { |
| | | throw new ServiceException("登录失败,请稍后重试"); |
| | | } |
| | | // 角色集合 |
| | | Set<String> roles = permissionService.getRolePermission(user); |
| | | // 权限集合 |
| | | List<SysMenu> menuPermission = permissionService.getMenuPermission(user); |
| | | LoginUser userInfo = new LoginUser(); |
| | | userInfo.setSysUser(user); |
| | | userInfo.setRoles(roles); |
| | | userInfo.setPermissions(menuPermission); |
| | | |
| | | if (StringUtils.isNull(user)) { |
| | | recordLogService.recordLogininfor(request, null, username, Constants.LOGIN_FAIL_STATUS, "登录用户不存在"); |
| | | throw new ServiceException("用户名/密码错误"); |
| | | } |
| | | |
| | | // 用户名或密码为空 错误 |
| | | if (StringUtils.isAnyBlank(username, password)) { |
| | | recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户/密码必须填写"); |
| | | throw new ServiceException("用户/密码必须填写"); |
| | | } |
| | | // 密码如果不在指定范围内 错误 |
| | | if (password.length() < UserConstants.PASSWORD_MIN_LENGTH |
| | | || password.length() > UserConstants.PASSWORD_MAX_LENGTH) { |
| | | recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户密码不在指定范围"); |
| | | throw new ServiceException("用户密码不在指定范围"); |
| | | } |
| | | // 用户名不在指定范围内 错误 |
| | | if (username.length() < UserConstants.USERNAME_MIN_LENGTH |
| | | || username.length() > UserConstants.USERNAME_MAX_LENGTH) { |
| | | recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户名不在指定范围"); |
| | | throw new ServiceException("用户名不在指定范围"); |
| | | } |
| | | // IP黑名单校验 |
| | | String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); |
| | | if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) { |
| | | recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "很遗憾,访问IP已被列入系统黑名单"); |
| | | throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); |
| | | } |
| | | |
| | | if (user.getDeleted()) { |
| | | recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "对不起,您的账号已被删除"); |
| | | throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); |
| | | } |
| | | if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { |
| | | recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户已停用,请联系管理员"); |
| | | throw new ServiceException("对不起,您的账号:" + username + " 已停用"); |
| | | } |
| | | passwordService.validate(user, password, request); |
| | | // recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_SUCCESS_STATUS, "登录成功"); |
| | | return userInfo; |
| | | } |
| | | |
| | | public void logout(String loginName, HttpServletRequest request) { |
| | | recordLogService.recordLogininfor(request, null, loginName, Constants.LOGIN_SUCCESS_STATUS, "退出成功"); |
| | | } |
| | | |
| | | /** |
| | | * 注册 |
| | | */ |
| | | public void register(String username, String password, HttpServletRequest request) { |
| | | // 用户名或密码为空 错误 |
| | | if (StringUtils.isAnyBlank(username, password)) { |
| | | throw new ServiceException("用户/密码必须填写"); |
| | | } |
| | | if (username.length() < UserConstants.USERNAME_MIN_LENGTH |
| | | || username.length() > UserConstants.USERNAME_MAX_LENGTH) { |
| | | throw new ServiceException("账户长度必须在2到20个字符之间"); |
| | | } |
| | | if (password.length() < UserConstants.PASSWORD_MIN_LENGTH |
| | | || password.length() > UserConstants.PASSWORD_MAX_LENGTH) { |
| | | throw new ServiceException("密码长度必须在5到20个字符之间"); |
| | | } |
| | | |
| | | // 注册用户信息 |
| | | SysUser sysUser = new SysUser(); |
| | | sysUser.setNickName(username); |
| | | sysUser.setPassword(SecurityUtils.encryptPassword(password)); |
| | | // R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER); |
| | | // |
| | | // if (R.FAIL == registerResult.getCode()) { |
| | | // throw new ServiceException(registerResult.getMsg()); |
| | | // } |
| | | recordLogService.recordLogininfor(request, sysUser.getId().intValue(), username, Constants.LOGIN_SUCCESS_STATUS, "注册成功"); |
| | | } |
| | | |
| | | public LoginOperationUser operationPasswordLogin(String phoneNumber, String password, HttpServletRequest request) { |
| | | LoginOperationUser loginOperationUser = new LoginOperationUser(); |
| | | phoneNumber = phoneNumber.trim(); |
| | | // 查询运维用户信息 |
| | | XpOperationsUser operationsUser = operationsUserService.lambdaQuery().eq( |
| | | XpOperationsUser::getPhoneNumber, phoneNumber |
| | | ).last("limit 1").one(); |
| | | if (StringUtils.isNull(operationsUser)) { |
| | | throw new ServiceException("账号或密码错误!"); |
| | | } |
| | | if (!operationsUser.getStatus()){ |
| | | throw new ServiceException("账号已禁用!"); |
| | | } |
| | | // todo 查询运维人员角色集合 |
| | | // todo 权限集合 |
| | | // 用户名或密码为空 错误 |
| | | if (StringUtils.isAnyBlank(phoneNumber, password)) { |
| | | throw new ServiceException("用户/验证码必须填写"); |
| | | } |
| | | passwordService.validateOperationsUser(operationsUser, password, request); |
| | | loginOperationUser.setXpOperationsUser(operationsUser); |
| | | return loginOperationUser; |
| | | } |
| | | public LoginOperationUser verificationCodeLogin(String phoneNumber, String code, HttpServletRequest request) { |
| | | LoginOperationUser loginOperationUser = new LoginOperationUser(); |
| | | phoneNumber = phoneNumber.trim(); |
| | | // 查询运维用户信息 |
| | | XpOperationsUser operationsUser = operationsUserService.lambdaQuery().eq( |
| | | XpOperationsUser::getPhoneNumber, phoneNumber |
| | | ).last("limit 1").one(); |
| | | if (StringUtils.isNull(operationsUser)) { |
| | | throw new ServiceException("验证码错误!"); |
| | | } |
| | | if (!operationsUser.getStatus()){ |
| | | throw new ServiceException("账号已禁用!"); |
| | | } |
| | | if (StringUtils.isAnyBlank(phoneNumber, code)) { |
| | | throw new ServiceException("用户/验证码必须填写"); |
| | | } |
| | | String verificationCode = redisService.getCacheObject(VerificationCodeConstants.LOGIN_CODE + phoneNumber); |
| | | if (StringUtils.isBlank(verificationCode)){ |
| | | throw new ServiceException("验证码已过期!"); |
| | | } |
| | | if (!verificationCode.equals(code)){ |
| | | throw new ServiceException("验证码错误!"); |
| | | } |
| | | // todo 查询运维人员角色集合 |
| | | // todo 权限集合 |
| | | loginOperationUser.setXpOperationsUser(operationsUser); |
| | | return loginOperationUser; |
| | | } |
| | | public Boolean verificationCodeUpdate(UpdatePasswordDTO updatePasswordDTO, HttpServletRequest request) { |
| | | String phoneNumber = updatePasswordDTO.getPhoneNumber(); |
| | | String code = updatePasswordDTO.getVerificationCode(); |
| | | phoneNumber = phoneNumber.trim(); |
| | | // 查询运维用户信息 |
| | | XpOperationsUser operationsUser = operationsUserService.lambdaQuery().eq( |
| | | XpOperationsUser::getPhoneNumber, phoneNumber |
| | | ).last("limit 1").one(); |
| | | if (StringUtils.isNull(operationsUser)) { |
| | | throw new ServiceException("验证码错误!"); |
| | | } |
| | | if (!operationsUser.getStatus()){ |
| | | throw new ServiceException("账号已禁用!"); |
| | | } |
| | | if (StringUtils.isAnyBlank(phoneNumber, code)) { |
| | | throw new ServiceException("用户/验证码必须填写"); |
| | | } |
| | | String verificationCode = redisService.getCacheObject(VerificationCodeConstants.UPDATE_PASSWORD_CODE + phoneNumber); |
| | | if (StringUtils.isBlank(verificationCode)){ |
| | | throw new ServiceException("验证码已过期!"); |
| | | } |
| | | if (!verificationCode.equals(code)){ |
| | | throw new ServiceException("验证码错误!"); |
| | | } |
| | | if (!updatePasswordDTO.getNewPassword().equals(updatePasswordDTO.getConfirmPassword())){ |
| | | throw new ServiceException("新密码和确认密码不一致!"); |
| | | } |
| | | operationsUser.setPassword(SecurityUtils.encryptPassword(updatePasswordDTO.getNewPassword())); |
| | | return operationsUserService.updateById(operationsUser); |
| | | } |
| | | } |
| File was renamed from xp-service/xp-account/src/main/java/com/xiaopeng/account/service/SysPasswordService.java |
| | |
| | | package com.xiaopeng.account.service; |
| | | package com.xiaopeng.account.service.impl; |
| | | |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | import com.xiaopeng.api.model.account.SysUser; |
| | | import com.xiaopeng.api.model.account.XpOperationsUser; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | import com.xiaopeng.common.core.constant.CacheConstants; |
| | |
| | | { |
| | | return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); |
| | | } |
| | | public boolean matchesOperationsUser(XpOperationsUser user, String rawPassword) |
| | | { |
| | | return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); |
| | | } |
| | | |
| | | public void clearLoginRecordCache(String loginName) |
| | | { |
| | |
| | | redisService.deleteObject(getCacheKey(loginName)); |
| | | } |
| | | } |
| | | |
| | | public void validateOperationsUser(XpOperationsUser operationsUser, String password, HttpServletRequest request) { |
| | | String phoneNumber = operationsUser.getPhoneNumber(); |
| | | |
| | | Integer retryCount = redisService.getCacheObject(getCacheKey(phoneNumber)); |
| | | |
| | | if (retryCount == null) |
| | | { |
| | | retryCount = 0; |
| | | } |
| | | |
| | | if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) |
| | | { |
| | | String errMsg = String.format("密码输入错误%s次,帐户锁定%s分钟", maxRetryCount, lockTime); |
| | | throw new ServiceException(errMsg); |
| | | } |
| | | |
| | | if (!matchesOperationsUser(operationsUser, password)) |
| | | { |
| | | retryCount = retryCount + 1; |
| | | redisService.setCacheObject(getCacheKey(phoneNumber), retryCount, lockTime, TimeUnit.MINUTES); |
| | | throw new ServiceException("用户名/密码错误"); |
| | | } |
| | | else |
| | | { |
| | | clearLoginRecordCache(phoneNumber); |
| | | } |
| | | } |
| | | } |
| File was renamed from xp-service/xp-account/src/main/java/com/xiaopeng/account/service/SysRecordLogService.java |
| | |
| | | package com.xiaopeng.account.service; |
| | | package com.xiaopeng.account.service.impl; |
| | | |
| | | import com.xiaopeng.api.model.operation.SysLoginLog; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | package com.xiaopeng.account.vo; |
| | | |
| | | import com.ruoyi.system.api.domain.SysUser; |
| | | import com.xiaopeng.api.model.account.SysUser; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | |
| | | package com.xiaopeng.account.vo; |
| | | |
| | | //import com.ruoyi.management.api.model.TCompanyShop; |
| | | import com.ruoyi.system.api.domain.SysUser; |
| | | import com.xiaopeng.api.model.account.SysUser; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | |
| | | public class AutomaticPilotApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(AutomaticPilotApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 自动驾驶模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 自动驾驶模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| | |
| | | public class ItineraryApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(ItineraryApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 行程模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 行程模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| | |
| | | public class MaintenanceApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(MaintenanceApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 运维模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 运维模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.maintenance.controller; |
| | | |
| | | import com.xiaopeng.api.vo.account.LoginOperationUser; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.common.redis.service.RedisService; |
| | | import com.xiaopeng.common.security.service.TokenService; |
| | | import com.xiaopeng.maintenance.query.WorkBenchQuery; |
| | | import com.xiaopeng.maintenance.service.XpTaskService; |
| | | import com.xiaopeng.maintenance.vo.WorkBenchVO; |
| | | import io.seata.spring.annotation.GlobalTransactional; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | /** |
| | | * token 控制 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Slf4j |
| | | @RestController |
| | | @Api(tags = "运维APP-工作台") |
| | | public class WorkbenchController { |
| | | @Autowired |
| | | private TokenService tokenService; |
| | | |
| | | @Resource |
| | | private XpTaskService xpTaskService; |
| | | |
| | | |
| | | @Autowired |
| | | private RedisService redisService; |
| | | |
| | | @ApiOperation(value = "工作台") |
| | | @PostMapping("/api/v1/workbench") |
| | | public R<PageInfo<WorkBenchVO>> workbench(@RequestBody WorkBenchQuery query) { |
| | | LoginOperationUser loginOperationUser = tokenService.getLoginOperationUser(); |
| | | query.setOperationId(loginOperationUser.getId()); |
| | | // 获取任务记录 |
| | | PageInfo<WorkBenchVO> pageInfo= xpTaskService.workbench( query); |
| | | return R.ok(pageInfo); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | package com.xiaopeng.maintenance.mapper; |
| | | |
| | | import com.xiaopeng.api.model.maintenance.XpTask; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.xiaopeng.api.model.maintenance.XpTask; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.maintenance.query.WorkBenchQuery; |
| | | import com.xiaopeng.maintenance.vo.WorkBenchVO; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 任务管理 Mapper 接口 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @author WuGuanFengYue |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpTaskMapper extends BaseMapper<XpTask> { |
| | | |
| | | List<WorkBenchVO> workbench(@Param("pageInfo") PageInfo<WorkBenchVO> pageInfo, @Param("query")WorkBenchQuery query); |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.maintenance.query; |
| | | |
| | | import com.xiaopeng.common.core.web.page.BasePage; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | @ApiModel(value = "运维APP工作台DTO") |
| | | public class WorkBenchQuery extends BasePage { |
| | | @ApiModelProperty(value = "当前登陆人id") |
| | | private Long operationId; |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.maintenance.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xiaopeng.api.model.maintenance.XpTask; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.maintenance.query.WorkBenchQuery; |
| | | import com.xiaopeng.maintenance.vo.WorkBenchVO; |
| | | |
| | | /** |
| | | * <p> |
| | | * 任务管理 服务类 |
| | | * </p> |
| | | * |
| | | * @author WuGuanFengYue |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpTaskService extends IService<XpTask> { |
| | | |
| | | PageInfo<WorkBenchVO> workbench(WorkBenchQuery query); |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.maintenance.service; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xiaopeng.api.model.maintenance.XpVehicle; |
| | | |
| | | /** |
| | | * <p> |
| | | * 车辆管理 服务类 |
| | | * </p> |
| | | * |
| | | * @author WuGuanFengYue |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpVehicleService extends IService<XpVehicle> { |
| | | |
| | | } |
| | |
| | | package com.xiaopeng.maintenance.service.impl; |
| | | |
| | | import com.xiaopeng.api.model.maintenance.XpTask; |
| | | import com.xiaopeng.api.mapper.XpTaskMapper; |
| | | import com.xiaopeng.api.service.IXpTaskService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xiaopeng.api.model.maintenance.XpTask; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.maintenance.mapper.XpTaskMapper; |
| | | import com.xiaopeng.maintenance.query.WorkBenchQuery; |
| | | import com.xiaopeng.maintenance.service.XpTaskService; |
| | | import com.xiaopeng.maintenance.vo.WorkBenchVO; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 任务管理 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @author WuGuanFengYue |
| | | * @since 2026-02-03 |
| | | */ |
| | | @Service |
| | | public class XpTaskServiceImpl extends ServiceImpl<XpTaskMapper, XpTask> implements IXpTaskService { |
| | | public class XpTaskServiceImpl extends ServiceImpl<XpTaskMapper, XpTask> implements XpTaskService { |
| | | |
| | | @Override |
| | | public PageInfo<WorkBenchVO> workbench(WorkBenchQuery query) { |
| | | PageInfo<WorkBenchVO> pageInfo = new PageInfo<>(query.getPageCurr(),query.getPageSize()); |
| | | List<WorkBenchVO> list = this.baseMapper.workbench(pageInfo,query); |
| | | pageInfo.setRecords( list); |
| | | return pageInfo; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.maintenance.vo; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.xiaopeng.api.model.maintenance.XpTask; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import okhttp3.internal.concurrent.Task; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | @Data |
| | | @ApiModel(value = "运维APP工作台VO") |
| | | public class WorkBenchVO extends XpTask { |
| | | @ApiModelProperty(value = "车辆颜色") |
| | | private String vehicleColor; |
| | | @ApiModelProperty(value = "车辆图片") |
| | | private String vehiclePictures; |
| | | @ApiModelProperty(value = "车辆vin码") |
| | | private String vehicleVin; |
| | | @ApiModelProperty(value = "车牌号") |
| | | private String plateNumber; |
| | | @ApiModelProperty(value = "任务类型名称") |
| | | private String taskTypeName; |
| | | } |
| | |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xiaopeng.maintenance.mapper.XpTaskMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xiaopeng.api.model.maintenance.XpTask"> |
| | | <id column="id" property="id" /> |
| | | <result column="task_code" property="taskCode" /> |
| | | <result column="task_category" property="taskCategory" /> |
| | | <result column="task_type_id" property="taskTypeId" /> |
| | | <result column="task_urgency_level" property="taskUrgencyLevel" /> |
| | | <result column="task_description" property="taskDescription" /> |
| | | <result column="vehicle_location" property="vehicleLocation" /> |
| | | <result column="vehicle_id" property="vehicleId" /> |
| | | <result column="vehicle_lon" property="vehicleLon" /> |
| | | <result column="vehicle_lat" property="vehicleLat" /> |
| | | <result column="handle_user_id" property="handleUserId" /> |
| | | <result column="handle_time" property="handleTime" /> |
| | | <result column="assignee_user_id" property="assigneeUserId" /> |
| | | <result column="assignee_time" property="assigneeTime" /> |
| | | <result column="report_user_id" property="reportUserId" /> |
| | | <result column="report_time" property="reportTime" /> |
| | | <result column="status" property="status" /> |
| | | <result column="is_deleted" property="isDeleted" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | id, task_code, task_category, task_type_id, task_urgency_level, task_description, vehicle_location, vehicle_id, vehicle_lon, vehicle_lat, handle_user_id, handle_time, assignee_user_id, assignee_time, report_user_id, report_time, status, is_deleted, create_time, update_time, create_by, update_by |
| | | </sql> |
| | | <select id="workbench" resultType="com.xiaopeng.maintenance.vo.WorkBenchVO"> |
| | | select t1.*,t2.vehicle_vin as vehicleVin,t2.plate_number as plateNumber, |
| | | t2.vehicle_color as vehicleColor,t2.vehicle_pictures as vehiclePictures |
| | | from xp_task t1 |
| | | left join xp_vehicle t2 on t1.vehicle_id = t2.id |
| | | where t1.handle_user_id = #{query.operationId} |
| | | and t1.status = 1 |
| | | and t1.is_deleted = 0 |
| | | order by t1.assignee_time asc |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | <version>2.6</version> |
| | | <scope>compile</scope> |
| | | </dependency> |
| | | |
| | | <!--mongodb--> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-data-mongodb</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | <build> |
| | |
| | | public class MapApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(MapApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 地图模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 地图模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.map.controller; |
| | | |
| | | |
| | | import com.xiaopeng.api.vo.operation.XpElectronicFenceVo; |
| | | import com.xiaopeng.common.core.web.controller.BaseController; |
| | | import com.xiaopeng.common.core.web.domain.AjaxResult; |
| | | import com.xiaopeng.map.service.XpElectronicFenceAreaService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Slf4j |
| | | @RestController |
| | | @RequestMapping("/base/v1/mini-program") |
| | | @Api(tags = "电子围栏") |
| | | public class ElectronicFenceController extends BaseController { |
| | | |
| | | private final XpElectronicFenceAreaService xpElectronicFenceAreaService; |
| | | |
| | | public ElectronicFenceController(XpElectronicFenceAreaService xpElectronicFenceAreaService) { |
| | | this.xpElectronicFenceAreaService = xpElectronicFenceAreaService; |
| | | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取地图开放区域围栏 |
| | | * @return |
| | | */ |
| | | @ApiOperation(value = "获取地图开放区域围栏",tags = {"小程序-获取地图开放区域围栏"},response = XpElectronicFenceVo.class) |
| | | @GetMapping("/cities/list") |
| | | public AjaxResult<List<XpElectronicFenceVo>> citiesList() { |
| | | return success(xpElectronicFenceAreaService.citiesList()); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.map.mapper; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.xiaopeng.api.model.operation.XpElectronicFenceArea; |
| | | |
| | | /** |
| | | * <p> |
| | | * 电子围栏区域构成 Mapper 接口 |
| | | * </p> |
| | | * |
| | | * @author liu |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpElectronicFenceAreaMapper extends BaseMapper<XpElectronicFenceArea> { |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.map.mapper; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.xiaopeng.api.model.operation.XpElectronicFence; |
| | | |
| | | /** |
| | | * <p> |
| | | * 电子围栏 Mapper 接口 |
| | | * </p> |
| | | * |
| | | * @author liu |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpElectronicFenceMapper extends BaseMapper<XpElectronicFence> { |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.map.service; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xiaopeng.api.model.operation.XpElectronicFenceArea; |
| | | import com.xiaopeng.api.vo.operation.XpElectronicFenceVo; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 电子围栏区域构成 服务类 |
| | | * </p> |
| | | * |
| | | * @author liu |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpElectronicFenceAreaService extends IService<XpElectronicFenceArea> { |
| | | |
| | | List<XpElectronicFenceVo> citiesList(); |
| | | |
| | | |
| | | |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.map.service; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xiaopeng.api.model.operation.XpElectronicFence; |
| | | |
| | | /** |
| | | * <p> |
| | | * 电子围栏 服务类 |
| | | * </p> |
| | | * |
| | | * @author liu |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpElectronicFenceService extends IService<XpElectronicFence> { |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取电子围栏列表 |
| | | */ |
| | | List<XpElectronicFenceVo> getXpElectronicFenceList(String cityCode); |
| | | |
| | | |
| | | /** |
| | | * 判断当前位置是否在运营区域内 |
| | | */ |
| | | Boolean isInElectronicFence(Double latitude, Double longitude,String cityCode); |
| | | } |
| | | |
| New file |
| | |
| | | package com.xiaopeng.map.service.serviceimpl; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xiaopeng.api.model.operation.XpElectronicFenceArea; |
| | | import com.xiaopeng.api.vo.operation.XpElectronicFenceVo; |
| | | import com.xiaopeng.map.mapper.XpElectronicFenceAreaMapper; |
| | | import com.xiaopeng.map.service.XpElectronicFenceAreaService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 电子围栏区域构成 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author liu |
| | | * @since 2026-02-03 |
| | | */ |
| | | @Service |
| | | public class XpElectronicFenceAreaServiceImpl extends ServiceImpl<XpElectronicFenceAreaMapper, XpElectronicFenceArea> implements XpElectronicFenceAreaService { |
| | | |
| | | @Override |
| | | public List<XpElectronicFenceVo> citiesList() { |
| | | return null; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.map.service.serviceimpl; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xiaopeng.api.model.operation.XpElectronicFence; |
| | | import com.xiaopeng.api.model.operation.XpOpenCity; |
| | | import com.xiaopeng.api.vo.operation.XpElectronicFenceVo; |
| | | import com.xiaopeng.map.mapper.XpElectronicFenceAreaMapper; |
| | | import com.xiaopeng.map.mapper.XpElectronicFenceMapper; |
| | | import com.xiaopeng.map.service.XpElectronicFenceService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | | * 电子围栏 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author liu |
| | | * @since 2026-02-03 |
| | | */ |
| | | @Service |
| | | public class XpElectronicFenceServiceImpl extends ServiceImpl<XpElectronicFenceMapper, XpElectronicFence> implements XpElectronicFenceService { |
| | | |
| | | |
| | | @Resource |
| | | private XpOpenCityMapper xpOpenCityMapper; |
| | | |
| | | @Resource |
| | | private XpElectronicFenceAreaMapper xpElectronicFenceAreaMapper; |
| | | |
| | | @Override |
| | | public List<XpElectronicFenceVo> getXpElectronicFenceList(String cityCode) { |
| | | // 通过code找到电子围栏信息 |
| | | // TODO 魔法数字 |
| | | List<XpOpenCity> xpOpenCities = xpOpenCityMapper.selectList(new LambdaQueryWrapper<XpOpenCity>().eq(XpOpenCity::getCityCode, cityCode).eq(XpOpenCity::getStatus, 1)); |
| | | if (!xpOpenCities.isEmpty()) { |
| | | List<Long> openCityIds = xpOpenCities.stream().map(XpOpenCity::getId).collect(Collectors.toList()); |
| | | |
| | | } |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | @Override |
| | | public Boolean isInElectronicFence(Double latitude, Double longitude,String cityCode) { |
| | | |
| | | // 获取所有可用的电子围栏信息 |
| | | |
| | | return null; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 通过一个点位 判断是否在某个电子围栏内 |
| | | */ |
| | | private static boolean isInElectronicFence(double lon, double lat,List<String> fencePoints) { |
| | | boolean contains = false; |
| | | |
| | | for (String fencePoint : fencePoints) { |
| | | ArrayList<GeoPolygonUtil.GeoPoint> geoPoints = new ArrayList<>(); |
| | | String[] split = fencePoint.split(","); |
| | | for (String lonLat : split) { |
| | | String[] split1 = lonLat.split("_"); |
| | | GeoPolygonUtil.GeoPoint geoPoint = new GeoPolygonUtil.GeoPoint(Double.parseDouble(split1[0]), Double.parseDouble(split1[1])); |
| | | geoPoints.add(geoPoint); |
| | | } |
| | | contains = GeoPolygonUtil.contains(lon, lat, geoPoints); |
| | | if(contains){ |
| | | // 一旦在范围中直接返回true |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.map.vo; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.data.mongodb.core.geo.GeoJsonPolygon; |
| | | import org.springframework.data.mongodb.core.index.GeoSpatialIndexType; |
| | | import org.springframework.data.mongodb.core.index.GeoSpatialIndexed; |
| | | import org.springframework.data.mongodb.core.mapping.Document; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * 地理围栏-多边形 |
| | | * @author zhibing.pu |
| | | * @date 2023/4/29 23:53 |
| | | */ |
| | | @Data |
| | | @Document(collection = "geo_fencing") |
| | | public class GeoFencingPolygon implements Serializable { |
| | | private static final long serialVersionUID = 4508868382007529971L; |
| | | |
| | | private String id; |
| | | /** |
| | | * 站点id |
| | | */ |
| | | private Integer siteId; |
| | | /** |
| | | * 站点名称 |
| | | */ |
| | | private String name; |
| | | /** |
| | | * 多边形经纬度 |
| | | */ |
| | | @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE) |
| | | private GeoJsonPolygon geoJsonPolygon; |
| | | |
| | | } |
| New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xiaopeng.map.mapper.XpElectronicFenceAreaMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xiaopeng.api.model.operation.XpElectronicFenceArea"> |
| | | <id column="id" property="id" /> |
| | | <result column="electronic_id" property="electronicId" /> |
| | | <result column="area_name" property="areaName" /> |
| | | <result column="area_type" property="areaType" /> |
| | | <result column="area_description" property="areaDescription" /> |
| | | <result column="area_status" property="areaStatus" /> |
| | | <result column="fence_points" property="fencePoints" /> |
| | | <result column="is_deleted" property="isDeleted" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | id, electronic_id, area_name, area_type, area_description, area_status, fence_points, is_deleted, create_time, update_time, create_by, update_by |
| | | </sql> |
| | | |
| | | </mapper> |
| New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xiaopeng.map.mapper.XpElectronicFenceMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xiaopeng.api.model.operation.XpElectronicFence"> |
| | | <id column="id" property="id" /> |
| | | <result column="electronic_name" property="electronicName" /> |
| | | <result column="electronic_number" property="electronicNumber" /> |
| | | <result column="status" property="status" /> |
| | | <result column="effect_type" property="effectType" /> |
| | | <result column="effect_time" property="effectTime" /> |
| | | <result column="failure_type" property="failureType" /> |
| | | <result column="failure_time" property="failureTime" /> |
| | | <result column="operation_strategy" property="operationStrategy" /> |
| | | <result column="is_deleted" property="isDeleted" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | id, electronic_name, electronic_number, status, effect_type, effect_time, failure_type, failure_time, operation_strategy, is_deleted, create_time, update_time, create_by, update_by |
| | | </sql> |
| | | |
| | | </mapper> |
| | |
| | | public class OperationApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(OperationApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 运营模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 运营模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.operation.controller; |
| | | |
| | | import com.xiaopeng.api.model.operation.XpPoint; |
| | | import com.xiaopeng.api.vo.account.LoginOperationUser; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.common.redis.service.RedisService; |
| | | import com.xiaopeng.common.security.service.TokenService; |
| | | import com.xiaopeng.operation.query.PointMapQuery; |
| | | import com.xiaopeng.operation.service.XpPointService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | /** |
| | | * token 控制 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Slf4j |
| | | @RestController |
| | | @Api(tags = "运维APP-地图导航") |
| | | public class IndexMapController { |
| | | @Autowired |
| | | private TokenService tokenService; |
| | | |
| | | |
| | | @Resource |
| | | private XpPointService xpPointService; |
| | | |
| | | @Autowired |
| | | private RedisService redisService; |
| | | |
| | | @ApiOperation(value = "地图导航") |
| | | @PostMapping("/api/v1/pointMap") |
| | | public R<PageInfo<XpPoint>> pointMap(@RequestBody PointMapQuery query) { |
| | | LoginOperationUser loginOperationUser = tokenService.getLoginOperationUser(); |
| | | query.setOperationId(loginOperationUser.getId()); |
| | | // 获取任务记录 |
| | | PageInfo<XpPoint> pageInfo= xpPointService.pointMap( query); |
| | | return R.ok(pageInfo); |
| | | } |
| | | @ApiOperation(value = "点位详情") |
| | | @GetMapping("/api/v1/pointDetail") |
| | | public R<XpPoint> pointDetail(@RequestParam(value = "点位id", required = true)Long id) { |
| | | XpPoint xpPoint = xpPointService.getById(id); |
| | | return R.ok(xpPoint); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.common.core.utils.StringUtils; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.common.security.annotation.Logical; |
| | |
| | | public AjaxResult add(@RequestBody SysOperLog operLog) { |
| | | return toAjax(operLogService.insertOperlog(operLog)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 保存系统日志 |
| | | * @param sysOperLog |
| | | * @return |
| | | */ |
| | | @PostMapping("/saveLog") |
| | | public R saveLog(@RequestBody SysOperLog sysOperLog) { |
| | | operLogService.save(sysOperLog); |
| | | return R.ok(); |
| | | } |
| | | } |
| | |
| | | public class XpAgreementController extends BaseController { |
| | | |
| | | private final XpAgreementService xpAgreementService; |
| | | |
| | | public XpAgreementController(XpAgreementService xpAgreementService) { |
| | | this.xpAgreementService = xpAgreementService; |
| | | } |
| | | |
| | | @ApiOperation(value = "获取协议",tags = {"小程序首页"},response = XpAgreementVo.class) |
| | | @ApiOperation(value = "获取协议",tags = {"小程序-首页"},response = XpAgreementVo.class) |
| | | @GetMapping("/privacy/content/{type}") |
| | | public AjaxResult<XpAgreementVo> getContent(@PathVariable Integer type) { |
| | | return success(xpAgreementService.getContentByType(type)); |
| | |
| | | /** |
| | | * 用户同意隐私协议/法律条款操作 |
| | | */ |
| | | @ApiOperation(value = "用户同意隐私协议/法律条款",tags = {"用户协议"}) |
| | | @ApiOperation(value = "用户同意隐私协议/法律条款",tags = {"小程序-用户协议"}) |
| | | @PostMapping("/privacy/agreement") |
| | | @XpClientCheck(checkToken = false, checkOtpToken = true) |
| | | public AjaxResult<?> privacyAgreement(@RequestBody XpAgreementAppUserDto dto, HttpServletRequest request) { |
| | |
| | | } |
| | | |
| | | |
| | | // 获取banner列表 |
| | | @ApiOperation(value = "获取banner",tags = {"小程序首页"},response = XpBannerListVo.class) |
| | | /** |
| | | * 获取banner |
| | | * @return |
| | | */ |
| | | @ApiOperation(value = "获取banner",tags = {"小程序-获取banner"},response = XpBannerListVo.class) |
| | | @GetMapping("/getBannerList") |
| | | public AjaxResult<List<XpBannerListVo>> getBannerList() { |
| | | return success(xpBannerService.getXpBannerList()); |
| | |
| | | |
| | | |
| | | |
| | | @ApiOperation(value = "获取开通城市列表",tags = {"小程序首页"},response = XpOpenCityVo.class) |
| | | /** |
| | | * 获取开通城市列表 |
| | | * @return |
| | | */ |
| | | @ApiOperation(value = "获取开通城市列表",tags = {"小程序-开通城市列表"},response = XpOpenCityVo.class) |
| | | @GetMapping("/cities/list") |
| | | public AjaxResult<XpOpenCityVo> citiesList() { |
| | | return success(xpOpenCityService.citiesList()); |
| | |
| | | package com.xiaopeng.operation.controller; |
| | | |
| | | |
| | | import com.xiaopeng.api.model.operation.XpPoint; |
| | | import com.xiaopeng.common.core.web.controller.BaseController; |
| | | import com.xiaopeng.common.core.web.domain.AjaxResult; |
| | | import com.xiaopeng.operation.dto.NearestDto; |
| | | import com.xiaopeng.operation.service.XpPointService; |
| | | import com.xiaopeng.operation.vo.NearestVo; |
| | | import com.xiaopeng.operation.vo.XpOpenCityVo; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import org.springframework.stereotype.Controller; |
| | | import javax.validation.Valid; |
| | | |
| | | /** |
| | | * <p> |
| | | * 点位管理 前端控制器 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2026-02-03 |
| | | */ |
| | | @Controller |
| | | @RequestMapping("/xp-point") |
| | | public class XpPointController { |
| | | @Slf4j |
| | | @RestController |
| | | @RequestMapping("/base/v1/mini-program") |
| | | @Api(tags = "点位模块") |
| | | public class XpPointController extends BaseController { |
| | | |
| | | private final XpPointService xpPointService; |
| | | |
| | | public XpPointController(XpPointService xpPointService) { |
| | | this.xpPointService = xpPointService; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取附近上车站点 |
| | | */ |
| | | @ApiOperation(value = "获取附近上车站点",tags = {"小程序-附近上车站点"},response = XpPoint.class) |
| | | @RequestMapping("/pickup/nearest") |
| | | public AjaxResult<NearestVo> nearest(@RequestBody @Valid NearestDto dto) { |
| | | return success(xpPointService.nearest(dto)); |
| | | } |
| | | } |
| | |
| | | package com.xiaopeng.operation.controller; |
| | | |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.xiaopeng.common.core.domain.R; |
| | | import com.xiaopeng.api.model.operation.XpRegion; |
| | | import com.xiaopeng.operation.service.XpRegionService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import org.springframework.stereotype.Controller; |
| | | import java.io.BufferedReader; |
| | | import java.io.InputStreamReader; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 省市区三级联动 前端控制器 |
| | | * 省市管理 前端控制器 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @since 2026-02-03 |
| | | */ |
| | | @Controller |
| | | @RequestMapping("/xp-region") |
| | | @Api(tags = "省市管理") |
| | | @RestController |
| | | @RequestMapping("/base/v1/mini-program") |
| | | public class XpRegionController { |
| | | |
| | | private final XpRegionService regionService; |
| | | |
| | | |
| | | @Autowired |
| | | public XpRegionController(XpRegionService regionService) { |
| | | this.regionService = regionService; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 查询省市管理 |
| | | */ |
| | | @ApiOperation(value = "查询省市管理",tags = {"小程序-省市管理"},response = XpRegion.class) |
| | | @GetMapping(value = "/open/t-region/getRegion") |
| | | public R<List<List<XpRegion>>> geXpRegion() { |
| | | return R.ok(regionService.getXpRegion()); |
| | | } |
| | | |
| | | |
| | | /* |
| | | * 查询市 |
| | | */ |
| | | @ApiOperation(value = "查询市",tags = {"小程序-查询市"},response = XpRegion.class) |
| | | @PostMapping(value = "/open/t-region/getProvince") |
| | | public R<List<XpRegion>> getProvince() { |
| | | List<XpRegion> list = regionService.list(Wrappers.lambdaQuery(XpRegion.class).ne(XpRegion::getParentId, 0).orderByAsc(XpRegion::getInitial)); |
| | | return R.ok(list); |
| | | } |
| | | |
| | | } |
| | | |
| New file |
| | |
| | | package com.xiaopeng.operation.dto; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | |
| | | @Data |
| | | @ApiModel(value = "NearestDto", description = "附近上车站点") |
| | | public class NearestDto { |
| | | |
| | | @ApiModelProperty(value = "纬度") |
| | | @NotNull(message = "纬度不能为空") |
| | | private Double latitude; |
| | | |
| | | @ApiModelProperty(value = "经度") |
| | | @NotNull(message = "经度不能为空") |
| | | private Double longitude; |
| | | } |
| | |
| | | package com.xiaopeng.operation.mapper; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.xiaopeng.api.model.operation.XpPoint; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.operation.query.PointMapQuery; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 点位管理 Mapper 接口 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @author liu |
| | | * @author WuGuanFengYue |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpPointMapper extends BaseMapper<XpPoint> { |
| | | |
| | | List<XpPoint> pointMap(@Param("pageInfo") PageInfo<XpPoint> pageInfo,@Param("query") PointMapQuery query); |
| | | } |
| | |
| | | package com.xiaopeng.operation.mapper; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.xiaopeng.api.model.operation.XpRegion; |
| | | |
| | |
| | | * 省市区三级联动 Mapper 接口 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @author liu |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpRegionMapper extends BaseMapper<XpRegion> { |
| New file |
| | |
| | | package com.xiaopeng.operation.query; |
| | | |
| | | import com.xiaopeng.common.core.web.page.BasePage; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import io.swagger.models.auth.In; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | @ApiModel(value = "运维APP地图导航DTO") |
| | | public class PointMapQuery extends BasePage { |
| | | @ApiModelProperty(value = "当前登陆人id 前端忽略") |
| | | private Long operationId; |
| | | @ApiModelProperty(value = "点位类型 1=运营点位 2=测试点位") |
| | | private Integer pointType; |
| | | @ApiModelProperty(value = "运营状态 1=待启用 2=启用中 3=已停用 4=已失效") |
| | | private Integer operationStatus; |
| | | @ApiModelProperty(value = "用户当前经度") |
| | | private String lon; |
| | | @ApiModelProperty(value = "用户当前纬度") |
| | | private String lat; |
| | | @ApiModelProperty(value = "点位名称") |
| | | private String pointName; |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.operation.service; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xiaopeng.api.model.operation.XpPoint; |
| | | import com.xiaopeng.common.core.web.domain.AjaxResult; |
| | | import com.xiaopeng.operation.dto.NearestDto; |
| | | import com.xiaopeng.operation.vo.NearestVo; |
| | | |
| | | import javax.validation.Valid; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.operation.query.PointMapQuery; |
| | | |
| | | /** |
| | | * <p> |
| | | * 点位管理 服务类 |
| | | * </p> |
| | | * |
| | | * @author liu |
| | | * @author WuGuanFengYue |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpPointService extends IService<XpPoint> { |
| | | |
| | | /** |
| | | * 获取附近上车站点 |
| | | */ |
| | | NearestVo nearest(@Valid NearestDto dto); |
| | | PageInfo<XpPoint> pointMap(PointMapQuery query); |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.operation.service; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xiaopeng.api.model.operation.XpRegion; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 省市区三级联动 服务类 |
| | | * </p> |
| | | * |
| | | * @author liu |
| | | * @since 2026-02-03 |
| | | */ |
| | | public interface XpRegionService extends IService<XpRegion> { |
| | | |
| | | /** |
| | | * 查询省市管理 |
| | | * @return |
| | | */ |
| | | List<List<XpRegion>> getXpRegion(); |
| | | |
| | | } |
| | |
| | | package com.xiaopeng.operation.service.impl; |
| | | |
| | | import com.xiaopeng.api.model.operation.XpPoint; |
| | | import com.xiaopeng.operation.mapper.XpPointMapper; |
| | | import com.xiaopeng.operation.service.IXpPointService; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xiaopeng.api.model.operation.XpPoint; |
| | | import com.xiaopeng.operation.dto.NearestDto; |
| | | import com.xiaopeng.common.core.web.page.PageInfo; |
| | | import com.xiaopeng.operation.mapper.XpPointMapper; |
| | | import com.xiaopeng.operation.query.PointMapQuery; |
| | | import com.xiaopeng.operation.service.XpPointService; |
| | | import com.xiaopeng.operation.utils.map.FastDistanceCalculator; |
| | | import com.xiaopeng.operation.vo.NearestNextVo; |
| | | import com.xiaopeng.operation.vo.NearestVo; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | | * 点位管理 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @author liu |
| | | * @author WuGuanFengYue |
| | | * @since 2026-02-03 |
| | | */ |
| | | @Service |
| | | public class XpPointServiceImpl extends ServiceImpl<XpPointMapper, XpPoint> implements IXpPointService { |
| | | public class XpPointServiceImpl extends ServiceImpl<XpPointMapper, XpPoint> implements XpPointService { |
| | | |
| | | |
| | | |
| | | @Override |
| | | public NearestVo nearest(NearestDto dto) { |
| | | // 获取所有的站点信息 |
| | | List<XpPoint> list = list(new LambdaQueryWrapper<XpPoint>().eq(XpPoint::getOperationStatus, 1)); |
| | | NearestVo nearestVo = new NearestVo(); |
| | | List<NearestNextVo> nearestNextVos = new ArrayList<>(); |
| | | for (XpPoint xpPoint : list) { |
| | | // 计算距离 小于1000m的站点 |
| | | double v = FastDistanceCalculator.distanceFast(dto.getLatitude(), dto.getLongitude(), xpPoint.getPointLat(), xpPoint.getPointLon()); |
| | | if (v < 1000) { |
| | | NearestNextVo nearestNextVo = new NearestNextVo(); |
| | | nearestNextVo.setId(xpPoint.getId()); |
| | | nearestNextVo.setName(xpPoint.getPointName()); |
| | | nearestNextVo.setLatitude(xpPoint.getPointLat()); |
| | | nearestNextVo.setLongitude(xpPoint.getPointLon()); |
| | | nearestNextVo.setDistance(v); |
| | | nearestNextVo.setAddress(xpPoint.getPointAddress()); |
| | | nearestNextVo.setTime(xpPoint.getParkingTimeLimit()); |
| | | nearestNextVos.add(nearestNextVo); |
| | | } |
| | | } |
| | | if (!nearestNextVos.isEmpty()) { |
| | | nearestNextVos = nearestNextVos.stream().sorted(Comparator.comparing(NearestNextVo::getDistance)).collect(Collectors.toList()); |
| | | } |
| | | nearestVo.setPoints(nearestNextVos); |
| | | nearestVo.setTotal(nearestNextVos.size()); |
| | | return nearestVo; |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public PageInfo<XpPoint> pointMap(PointMapQuery query) { |
| | | PageInfo<XpPoint> pageInfo = new PageInfo<>(query.getPageCurr(),query.getPageSize()); |
| | | List<XpPoint> list = this.baseMapper.pointMap(pageInfo,query); |
| | | pageInfo.setRecords( list); |
| | | return pageInfo; |
| | | } |
| | | |
| | | } |
| | |
| | | package com.xiaopeng.operation.service.impl; |
| | | |
| | | import com.xiaopeng.api.model.operation.XpRegion; |
| | | import com.xiaopeng.operation.mapper.XpRegionMapper; |
| | | import com.xiaopeng.operation.service.IXpRegionService; |
| | | |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xiaopeng.operation.mapper.XpRegionMapper; |
| | | import com.xiaopeng.api.model.operation.XpRegion; |
| | | import com.xiaopeng.operation.service.XpRegionService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | | * 省市区三级联动 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author mitao |
| | | * @author liu |
| | | * @since 2026-02-03 |
| | | */ |
| | | @Service |
| | | public class XpRegionServiceImpl extends ServiceImpl<XpRegionMapper, XpRegion> implements IXpRegionService { |
| | | public class XpRegionServiceImpl extends ServiceImpl<XpRegionMapper, XpRegion> implements XpRegionService { |
| | | |
| | | @Override |
| | | public List<List<XpRegion>> getXpRegion() { |
| | | String[] initials = {"A", "B", "C", "D", "E", "F", |
| | | "G", "H", "I", "J", "K", "L", |
| | | "M", "N", "O", "P", "Q", "R", |
| | | "S", "T", "U", "V", "W", "X", "Y", "Z"}; |
| | | List<XpRegion> tRegions = this.baseMapper.selectList(Wrappers.lambdaQuery(XpRegion.class)); |
| | | List<List<XpRegion>> result = new ArrayList<>(); |
| | | for (String initial : initials) { |
| | | List<XpRegion> init = tRegions.stream().filter(e -> e.getInitial().equals(initial) && !e.getCode().contains("0000")).collect(Collectors.toList()); |
| | | result.add(init); |
| | | } |
| | | return result; |
| | | } |
| | | } |
| | |
| | | package com.xiaopeng.operation.utils; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.xiaopeng.operation.model.ServerCarModelWarpper; |
| | | import com.xiaopeng.operation.model.XpPricing; |
| | | import com.xiaopeng.operation.service.XpPricingService; |
| | | import com.xiaopeng.operation.utils.map.GDMapElectricFenceUtil; |
| | | import com.xiaopeng.operation.utils.map.GDMapGeocodingUtil; |
| | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.*; |
| | | |
| | | /** |
| New file |
| | |
| | | package com.xiaopeng.operation.utils.map; |
| | | |
| | | public class FastDistanceCalculator { |
| | | private static final double R = 6371.0; // 地球半径(千米) |
| | | private static final double DEG_TO_RAD = Math.PI / 180.0; |
| | | |
| | | /** |
| | | * 快速近似算法 - 性能极高,误差<0.5% |
| | | * 适合需要大量计算的场景(如KNN、聚类) |
| | | */ |
| | | public static double distanceFast(double lat1, double lon1, |
| | | double lat2, double lon2) { |
| | | double x = (lon2 - lon1) * DEG_TO_RAD * Math.cos((lat1 + lat2) * 0.5 * DEG_TO_RAD); |
| | | double y = (lat2 - lat1) * DEG_TO_RAD; |
| | | return R * Math.sqrt(x * x + y * y); |
| | | } |
| | | |
| | | /** |
| | | * 平面近似 - 极高性能,适用于小范围(城市内) |
| | | */ |
| | | public static double distanceFlatApprox(double lat1, double lon1, |
| | | double lat2, double lon2) { |
| | | // 每度纬度约111km,每度经度随纬度变化 |
| | | double kmPerDegreeLat = 111.0; |
| | | double kmPerDegreeLon = 111.0 * Math.cos((lat1 + lat2) * 0.5 * DEG_TO_RAD); |
| | | |
| | | double dLat = lat2 - lat1; |
| | | double dLon = lon2 - lon1; |
| | | |
| | | return Math.sqrt(Math.pow(dLat * kmPerDegreeLat, 2) + |
| | | Math.pow(dLon * kmPerDegreeLon, 2)); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.operation.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | @ApiModel(value = "NearestNextVo对象", description = "附近站点二级Vo") |
| | | public class NearestNextVo { |
| | | |
| | | @ApiModelProperty(value = "站点id") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "站点名称") |
| | | private String name; |
| | | |
| | | @ApiModelProperty(value = "站点经度") |
| | | private Double latitude; |
| | | |
| | | @ApiModelProperty(value = "站点纬度") |
| | | private Double longitude; |
| | | |
| | | @ApiModelProperty(value = "距离") |
| | | private Double distance; |
| | | |
| | | @ApiModelProperty(value = "站点地址") |
| | | private String address; |
| | | |
| | | @ApiModelProperty(value = "停车时长") |
| | | private Integer time; |
| | | |
| | | @ApiModelProperty(value = "开始时间") |
| | | private String startTime; |
| | | |
| | | @ApiModelProperty(value = "结束时间") |
| | | private String endTime; |
| | | |
| | | |
| | | } |
| New file |
| | |
| | | package com.xiaopeng.operation.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Data |
| | | @ApiModel(value = "NearestNextVo对象", description = "附近站点vo") |
| | | public class NearestVo { |
| | | |
| | | private List<NearestNextVo> points; |
| | | |
| | | |
| | | private Integer total; |
| | | } |
| | |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xiaopeng.operation.mapper.XpPointMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xiaopeng.api.model.operation.XpPoint"> |
| | | <id column="id" property="id" /> |
| | | <result column="point_name" property="pointName" /> |
| | | <result column="point_poi" property="pointPoi" /> |
| | | <result column="point_number" property="pointNumber" /> |
| | | <result column="operation_status" property="operationStatus" /> |
| | | <result column="point_type" property="pointType" /> |
| | | <result column="verification_status" property="verificationStatus" /> |
| | | <result column="parking_time_limit" property="parkingTimeLimit" /> |
| | | <result column="operation_type" property="operationType" /> |
| | | <result column="effective_period" property="effectivePeriod" /> |
| | | <result column="effective_time_period" property="effectiveTimePeriod" /> |
| | | <result column="remarks" property="remarks" /> |
| | | <result column="point_pictures" property="pointPictures" /> |
| | | <result column="point_lon" property="pointLon" /> |
| | | <result column="point_lat" property="pointLat" /> |
| | | <result column="is_deleted" property="isDeleted" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="update_time" property="updateTime" /> |
| | | <result column="create_by" property="createBy" /> |
| | | <result column="update_by" property="updateBy" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | id, point_name, point_poi, point_number, operation_status, point_type, verification_status, parking_time_limit, operation_type, effective_period, effective_time_period, remarks, point_pictures, point_lon, point_lat, is_deleted, create_time, update_time, create_by, update_by |
| | | </sql> |
| | | <select id="pointMap" resultType="com.xiaopeng.api.model.operation.XpPoint"> |
| | | select t1.*, |
| | | ROUND( |
| | | 6378.138 * 2 * ASIN( |
| | | SQRT( |
| | | POW( |
| | | SIN( |
| | | ( |
| | | #{query.lat} * PI() / 180 - t1.point_lat * PI() / 180 |
| | | ) / 2 |
| | | ), |
| | | 2 |
| | | ) + COS(#{query.lat} * PI() / 180) * COS(t1.point_lat * PI() / 180) * POW( |
| | | SIN( |
| | | ( |
| | | #{query.lon} * PI() / 180 - t1.point_lon * PI() / 180 |
| | | ) / 2 |
| | | ), |
| | | 2 |
| | | ) |
| | | ) |
| | | ) * 1000 |
| | | ) AS distance |
| | | from xp_point t1 |
| | | where t1.is_deleted = 0 |
| | | <if test="query.pointName != null and query.pointName != ''"> |
| | | and t1.point_name like concat('%',#{query.pointName},'%') |
| | | </if> |
| | | <if test="query.pointType != null"> |
| | | and t1.point_type = #{query.pointType} |
| | | </if> |
| | | <if test="query.operationStatus != null"> |
| | | and t1.operation_status = #{query.operationStatus} |
| | | </if> |
| | | order by distance asc |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.xiaopeng.operation.mapper.XpRegionMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.xiaopeng.api.model.operation.XpRegion"> |
| | | <id column="id" property="id" /> |
| | | <result column="name" property="name" /> |
| | | <result column="code" property="code" /> |
| | | <result column="citycode" property="citycode" /> |
| | | <result column="parent_id" property="parentId" /> |
| | | <result column="english" property="english" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | id, name, code, citycode, parentId, english, initial, lat, lon |
| | | id, name, code, citycode, parent_id, english |
| | | </sql> |
| | | |
| | | </mapper> |
| | |
| | | public class OrderApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(OrderApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 订单模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 订单模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| | |
| | | public class PaymentApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(PaymentApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 支付模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 支付模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| | |
| | | public class PushMessageApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(PushMessageApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 消息推送模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 消息推送模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| | |
| | | public class RemoteDrivingApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(RemoteDrivingApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 远程驾驶模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 远程驾驶模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| | |
| | | public class VehicleConvoyApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(VehicleConvoyApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 车辆车队模块启动成功 ლ(´ڡ`ლ)゙ "); |
| | | System.out.println("(♥◠‿◠)ノ゙ 车辆车队模块启动成功 ლ(´ڡ`ლ)゙ \n"); |
| | | } |
| | | } |
| | |
| | | type: nacos |
| | | nacos: |
| | | # 开发环境 |
| | | # server-addr: 192.168.110.169:8848 |
| | | # namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb |
| | | # group: DEFAULT_GROUP |
| | | # data-id: seata-server.properties |
| | | # username: nacos |
| | | # password: nacos |
| | | # 生产环境 |
| | | server-addr: 192.168.0.137:8848,192.168.0.123:8848 |
| | | namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a |
| | | server-addr: 192.168.110.80:8848 |
| | | namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1 |
| | | group: DEFAULT_GROUP |
| | | data-id: seata-server.properties |
| | | username: nacos |
| | | password: nacos |
| | | # 生产环境 |
| | | # server-addr: 192.168.0.137:8848,192.168.0.123:8848 |
| | | # namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a |
| | | # group: DEFAULT_GROUP |
| | | # data-id: seata-server.properties |
| | | # username: nacos |
| | | # password: nacos |
| | | registry: |
| | | type: nacos |
| | | nacos: |
| | | application: seata-server |
| | | # 开发环境 |
| | | # server-addr: 192.168.110.169:8848 |
| | | # namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb |
| | | # group: DEFAULT_GROUP |
| | | # username: nacos |
| | | # password: nacos |
| | | # 生产环境 |
| | | server-addr: 192.168.0.137:8848,192.168.0.123:8848 |
| | | namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a |
| | | server-addr: 192.168.110.80:8848 |
| | | namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1 |
| | | group: DEFAULT_GROUP |
| | | username: nacos |
| | | password: nacos |
| | | # 生产环境 |
| | | # server-addr: 192.168.0.137:8848,192.168.0.123:8848 |
| | | # namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a |
| | | # group: DEFAULT_GROUP |
| | | # username: nacos |
| | | # password: nacos |
| | | cloud: |
| | | nacos: |
| | | discovery: |
| | | # 开发环境 |
| | | # server-addr: 192.168.110.169:8848 # nacos注册中心地址 |
| | | # namespace: b5290bc2-e3aa-4988-8a7d-9c07e4e073cb # 命名空间 |
| | | # group: DEFAULT_GROUP |
| | | # application: seata-server #Nacos 中 Seata 名称 |
| | | # username: nacos |
| | | # password: nacos |
| | | # 生产环境 |
| | | server-addr: 192.168.0.137:8848,192.168.0.123:8848 |
| | | namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a |
| | | server-addr: 192.168.110.80:8848 |
| | | namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1 |
| | | group: DEFAULT_GROUP |
| | | application: seata-server #Nacos 中 Seata 名称 |
| | | username: nacos |
| | | password: nacos |
| | | # 生产环境 |
| | | # server-addr: 192.168.0.137:8848,192.168.0.123:8848 |
| | | # namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a |
| | | # group: DEFAULT_GROUP |
| | | # application: seata-server #Nacos 中 Seata 名称 |
| | | # username: nacos |
| | | # password: nacos |
| | | sentinel: |
| | | transport: |
| | | dashboard: 192.168.0.137:8080 # Sentinel控制台地址 |