Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/mx_charging_pile
84个文件已修改
1个文件已删除
15个文件已添加
| | |
| | | <artifactId>ruoyi-api-system</artifactId> |
| | | <version>${ruoyi.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-api-account</artifactId> |
| | | <version>${ruoyi.version}</version> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | </dependencyManagement> |
| | |
| | | @ApiModelProperty("1月2季3年") |
| | | private Integer type; |
| | | @ApiModelProperty("用户Id") |
| | | private Long userId; |
| | | private String userIds; |
| | | } |
| | |
| | | |
| | | @Data |
| | | public class PointsQueryDto extends BasePage { |
| | | @ApiModelProperty("用户id") |
| | | private Long userId; |
| | | @ApiModelProperty("1收入0支出") |
| | | private Integer type; |
New file |
| | |
| | | package com.ruoyi.account.api.dto; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.ruoyi.common.core.web.domain.BasePojo; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * <p> |
| | | * |
| | | * </p> |
| | | * |
| | | * @author luodangjia |
| | | * @since 2024-08-06 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = false) |
| | | @TableName("t_app_user") |
| | | @ApiModel(value="TAppUser对象", description="") |
| | | public class TAppUserDto extends BasePojo { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @ApiModelProperty(value = "主键") |
| | | @TableId("id") |
| | | private String id; |
| | | |
| | | @ApiModelProperty(value = "用户") |
| | | @TableField("name") |
| | | private String name; |
| | | |
| | | @ApiModelProperty(value = "手机号") |
| | | @TableField("phone") |
| | | private String phone; |
| | | |
| | | @ApiModelProperty(value = "头像") |
| | | @TableField("avatar") |
| | | private String avatar; |
| | | |
| | | @ApiModelProperty(value = "会员id") |
| | | @TableField("vip_id") |
| | | private Integer vipId; |
| | | |
| | | @ApiModelProperty(value = "会员到期时间") |
| | | @TableField("vip_end_time") |
| | | private LocalDateTime vipEndTime; |
| | | |
| | | @ApiModelProperty(value = "单位id") |
| | | @TableField("company_id") |
| | | private Integer companyId; |
| | | |
| | | @ApiModelProperty(value = "身份证号") |
| | | @TableField("id_card") |
| | | private String idCard; |
| | | |
| | | @ApiModelProperty(value = "认证状态(0=否,1=是)") |
| | | @TableField("auth_status") |
| | | private Integer authStatus; |
| | | |
| | | @ApiModelProperty(value = "微信openid") |
| | | @TableField("wx_openid") |
| | | private String wxOpenid; |
| | | |
| | | @ApiModelProperty(value = "支付宝openid") |
| | | @TableField("ali_openid") |
| | | private String aliOpenid; |
| | | |
| | | @ApiModelProperty(value = "积分") |
| | | @TableField("points") |
| | | private Integer points; |
| | | |
| | | @ApiModelProperty(value = "省名称") |
| | | @TableField("province") |
| | | private String province; |
| | | |
| | | @ApiModelProperty(value = "省区划代码") |
| | | @TableField("province_code") |
| | | private String provinceCode; |
| | | |
| | | @ApiModelProperty(value = "市名称") |
| | | @TableField("city") |
| | | private String city; |
| | | |
| | | @ApiModelProperty(value = "市区划代码") |
| | | @TableField("city_code") |
| | | private String cityCode; |
| | | |
| | | @ApiModelProperty(value = "状态(1=正常,2=冻结,3=注销)") |
| | | @TableField("status") |
| | | private Integer status; |
| | | |
| | | |
| | | |
| | | @ApiModelProperty(value = "最后一次登录时间") |
| | | @TableField("last_login_time") |
| | | private LocalDateTime lastLoginTime; |
| | | |
| | | |
| | | |
| | | |
| | | @ApiModelProperty(value = "标签名称") |
| | | @TableField(exist = false) |
| | | private String tagName; |
| | | @ApiModelProperty(value = "vip名称") |
| | | @TableField(exist = false) |
| | | private String vipName; |
| | | @ApiModelProperty("累计充电数") |
| | | @TableField(exist = false) |
| | | private Long orderCount; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ruoyi.account.api.dto; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | public class UnitChangeDto { |
| | | private String ids; |
| | | private Integer unitId; |
| | | } |
| | |
| | | @ApiModelProperty(value = "主键") |
| | | @TableId("id") |
| | | private Long id; |
| | | @TableField(exist = false) |
| | | private String uid; |
| | | |
| | | @ApiModelProperty(value = "用户") |
| | | @TableField("name") |
| | |
| | | @ApiModelProperty(value = "奖励积分") |
| | | @TableField("reward_points") |
| | | private Integer rewardPoints; |
| | | @ApiModelProperty(value = "礼盒标记") |
| | | @TableField("is_gift") |
| | | private Integer isGift; |
| | | |
| | | @ApiModelProperty(value = "添加时间") |
| | | @TableField("create_time") |
| | |
| | | @TableField("bank_account") |
| | | private String bankAccount; |
| | | |
| | | // @ApiModelProperty(value = "设置默认(0=否,1=是)") |
| | | // @TableField("default") |
| | | // private Integer default; |
| | | @ApiModelProperty(value = "设置默认(0=否,1=是)") |
| | | @TableField("is_default") |
| | | private Integer isDefault; |
| | | |
| | | |
| | | |
| | |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableLogic; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.ruoyi.common.core.web.domain.BasePojo; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | |
| | | @EqualsAndHashCode(callSuper = false) |
| | | @TableName("t_charging_pile_notification") |
| | | @ApiModel(value="TChargingPileNotification对象", description="") |
| | | public class TChargingPileNotification implements Serializable { |
| | | public class TChargingPileNotification extends BasePojo { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | |
| | | @ApiModelProperty(value = "通知内容") |
| | | @TableField("content") |
| | | private String content; |
| | | |
| | | @ApiModelProperty(value = "发送时间") |
| | | @TableField("create_time") |
| | | private LocalDateTime createTime; |
| | | |
| | | @ApiModelProperty(value = "删除状态(0=否,1=是)") |
| | | @TableField("del_flag") |
| | | @TableLogic |
| | | private Integer delFlag; |
| | | |
| | | |
| | | } |
| | |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @ApiModelProperty(value = "开票公司") |
| | | @TableField("invoicing_company") |
| | | private String invoicingCompany; |
| | | |
| | | @ApiModelProperty(value = "发票类型id") |
| | | @TableField("invoice_type_id") |
| | | private Integer invoiceTypeId; |
| | | |
| | | @ApiModelProperty(value = "发票类型(1=增值税普通发票,2=增值税专用发票)") |
| | | @ApiModelProperty(value = "发票类型") |
| | | @TableField("invoice_type") |
| | | private Integer invoiceType; |
| | | private String invoiceType; |
| | | |
| | | @ApiModelProperty(value = "发票材质(1=纸质发票,2=电子发票)") |
| | | @TableField("invoice_material") |
| | |
| | | @ApiModelProperty(value = "状态(1=待开票,2=开票中,3=已开票)") |
| | | @TableField("status") |
| | | private Integer status; |
| | | |
| | | |
| | | @ApiModelProperty(value = "添加时间") |
| | | @TableField("create_time") |
| | | private LocalDateTime createTime; |
| | | |
| | | @ApiModelProperty(value = "开票时间") |
| | | @TableField("billing_time") |
| | | private LocalDateTime billingTime; |
| | | |
| | | @ApiModelProperty(value = "开票人id") |
| | | @TableField("billing_user_id") |
| | | private Integer billingUserId; |
| | | |
| | | } |
| | |
| | | @TableField("invite_users_to_earn_points") |
| | | private String inviteUsersToEarnPoints; |
| | | |
| | | @ApiModelProperty(value = "签到得积分{\"num1\":1,\"num2\":[{\"num1\":1,\"num2\":1}]}") |
| | | @ApiModelProperty(value = "签到得积分{\"num1\":1,\"num2\":[\"1(多少天),2(多少分)\"]}") |
| | | @TableField("sign_in_for_points") |
| | | private String signInForPoints; |
| | | |
| | |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | |
| | | |
| | | @ApiModelProperty(value = "电费税率") |
| | | @TableField("electricity_tariff") |
| | | private Double electricityTariff; |
| | | private BigDecimal electricityTariff; |
| | | |
| | | @ApiModelProperty(value = "服务费税率") |
| | | @TableField("service_tariff") |
| | | private Double serviceTariff; |
| | | private BigDecimal serviceTariff; |
| | | |
| | | @ApiModelProperty(value = "增值服务费税率") |
| | | @TableField("added_service_tariff") |
| | | private Double addedServiceTariff; |
| | | private BigDecimal addedServiceTariff; |
| | | |
| | | |
| | | |
| | |
| | | @EqualsAndHashCode(callSuper = false) |
| | | @TableName("t_system_configuration") |
| | | @ApiModel(value="TSystemConfiguration对象", description="") |
| | | public class TSystemConfiguration extends BasePojo { |
| | | public class TSystemConfiguration implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | |
| | | private Integer standardCondition; |
| | | |
| | | @ApiModelProperty(value = "达标条件值JSON({\"day\":1,\"times\":5})") |
| | | @TableField("condition") |
| | | private String condition; |
| | | @TableField("conditions") |
| | | private String conditions; |
| | | |
| | | |
| | | |
| | |
| | | @TableField(exist = false) |
| | | private Long count; |
| | | |
| | | @ApiModelProperty(value = "前端展示用") |
| | | @TableField("type") |
| | | private Integer type; |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ruoyi.other.api.factory; |
| | | |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.other.api.domain.TInvoiceType; |
| | | import com.ruoyi.other.api.feignClient.InvoiceTypeClient; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.cloud.openfeign.FallbackFactory; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | |
| | | /** |
| | | * 商品服务降级处理 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class InvoiceTypeFallbackFactory implements FallbackFactory<InvoiceTypeClient> |
| | | { |
| | | private static final Logger log = LoggerFactory.getLogger(InvoiceTypeFallbackFactory.class); |
| | | |
| | | @Override |
| | | public InvoiceTypeClient create(Throwable throwable) { |
| | | log.error("开票类型失败:{}", throwable.getMessage()); |
| | | return new InvoiceTypeClient() { |
| | | |
| | | |
| | | @Override |
| | | public R<TInvoiceType> getInvoiceType(Integer id) { |
| | | throw new RuntimeException(throwable.getMessage()); |
| | | } |
| | | }; |
| | | } |
| | | } |
New file |
| | |
| | | package com.ruoyi.other.api.feignClient; |
| | | |
| | | import com.ruoyi.common.core.constant.ServiceNameConstants; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.other.api.domain.TInvoiceType; |
| | | import com.ruoyi.other.api.factory.InvoiceTypeFallbackFactory; |
| | | import org.springframework.cloud.openfeign.FeignClient; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2024/8/19 15:57 |
| | | */ |
| | | @FeignClient(contextId = "IntegralRuleClient", value = ServiceNameConstants.OTHER_SERVICE, fallbackFactory = InvoiceTypeFallbackFactory.class) |
| | | public interface InvoiceTypeClient { |
| | | |
| | | |
| | | /** |
| | | * 根据id获取发票类型 |
| | | * @param id |
| | | * @return |
| | | */ |
| | | @PostMapping("/t-invoice-type/getInvoiceType/{id}") |
| | | R<TInvoiceType> getInvoiceType(@PathVariable("id") Integer id); |
| | | } |
| | |
| | | com.ruoyi.other.api.factory.VipFallbackFactory |
| | | com.ruoyi.other.api.factory.IntegralRuleFallbackFactory |
| | | com.ruoyi.other.api.factory.GoodsFallbackFactory |
| | | com.ruoyi.other.api.factory.CouponFallbackFactory |
| | | com.ruoyi.other.api.factory.CouponFallbackFactory |
| | | com.ruoyi.other.api.factory.InvoiceTypeFallbackFactory |
| | |
| | | private SysLoginService sysLoginService; |
| | | @Resource |
| | | private SysUserClient userClient; |
| | | @Autowired |
| | | private RedisService redisService; |
| | | @Autowired |
| | | private AppUserClient appUserClient; |
| | | |
| | | |
| | | |
| | |
| | | return R.ok(); |
| | | } |
| | | |
| | | @DeleteMapping("logoutApplet") |
| | | public R<?> logoutApplet(HttpServletRequest request) { |
| | | String token = SecurityUtils.getToken(request); |
| | | if (StringUtils.isNotEmpty(token)) |
| | | { |
| | | // 删除用户缓存记录 |
| | | AuthUtil.logoutByToken(token); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @PostMapping("refresh") |
| | | public R<?> refresh(HttpServletRequest request) |
| | |
| | | // 用户注册 |
| | | sysLoginService.register(registerBody.getUsername(), registerBody.getPassword(), request); |
| | | return R.ok(); |
| | | } |
| | | |
| | | /** |
| | | * 获取验证码 |
| | | * |
| | | * @param phone 手机号 |
| | | * @return 结果 |
| | | */ |
| | | @ApiOperation(value = "获取验证码",notes = "获取验证码",tags = {"更换手机号获取验证码"}) |
| | | @GetMapping("getCode") |
| | | public AjaxResult getCode(@RequestParam("phone") String phone) |
| | | { |
| | | TAppUser appUser = appUserClient.selectByPhone(phone).getData(); |
| | | if (Objects.nonNull(appUser)){ |
| | | return AjaxResult.error("该手机号已绑定账号"); |
| | | } |
| | | String code = MsgUtil.createCode(); |
| | | redisService.setCacheObject(phone+Constants.APPLET,code,5L, TimeUnit.MINUTES); |
| | | String reqStr = MsgUtil.codeMsg(phone, code); |
| | | String result = HttpUtils.post(MsgConstants.SEND_URL, reqStr); |
| | | return AjaxResult.success(result); |
| | | } |
| | | |
| | | } |
| | |
| | | * 用户标识 |
| | | */ |
| | | public static final String USER_KEY = "user_key"; |
| | | |
| | | /** |
| | | * 用户类型(system/applet) |
| | | */ |
| | | public static final String USER_TYPE = "user_type"; |
| | | /** |
| | | * 小程序登录用户标识 |
| | | */ |
New file |
| | |
| | | package com.ruoyi.common.core.enums.status; |
| | | |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * @Description |
| | | * @Author xiaochen |
| | | * @Date 2023/6/8 16:42 |
| | | */ |
| | | public enum AppUserStatusEnum { |
| | | |
| | | |
| | | NORMAL(1, "正常"), |
| | | FREEZE(2, "冻结"), |
| | | LOGOFF(3, "注销"); |
| | | |
| | | @Getter |
| | | private String desc; |
| | | |
| | | |
| | | @Getter |
| | | private int code; |
| | | |
| | | |
| | | AppUserStatusEnum(int code, String desc) { |
| | | this.code = code; |
| | | this.desc = desc; |
| | | } |
| | | |
| | | /** |
| | | * 通过code获取枚举 |
| | | * |
| | | * @param code |
| | | * @return |
| | | */ |
| | | public static AppUserStatusEnum fromCode(Integer code) { |
| | | AppUserStatusEnum[] resultTypes = AppUserStatusEnum.values(); |
| | | for (AppUserStatusEnum resultType : resultTypes) { |
| | | if (code.equals(resultType.getCode())) { |
| | | return resultType; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | } |
| | |
| | | { |
| | | return getValue(claims, SecurityConstants.USER_KEY); |
| | | } |
| | | |
| | | /** |
| | | * 根据令牌获取用户类型 |
| | | * |
| | | * @param token 令牌 |
| | | * @return 用户类型 |
| | | */ |
| | | public static String getUserType(String token) |
| | | { |
| | | Claims claims = parseToken(token); |
| | | return getValue(claims, SecurityConstants.USER_TYPE); |
| | | } |
| | | |
| | | /** |
| | | * 根据令牌获取用户类型 |
| | | * |
| | | * @param claims 身份信息 |
| | | * @return 用户类型 |
| | | */ |
| | | public static String getUserType(Claims claims) |
| | | { |
| | | return getValue(claims, SecurityConstants.USER_TYPE); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 小程序根据令牌获取用户标识 |
| | |
| | | return encode; |
| | | } |
| | | |
| | | /** |
| | | /** phone 单词可拼接5000个号码 |
| | | * 桩故障(自动/手动):检测到【电站1】【编号】号桩设备离线,请及时查看处理! |
| | | * @param phone 手机号 |
| | | * @param site 站点名称 |
| | |
| | | Map<String, Object> claimsMap = new HashMap<String, Object>(); |
| | | claimsMap.put(SecurityConstants.USER_KEY, token); |
| | | claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId); |
| | | claimsMap.put(SecurityConstants.USER_TYPE, "system"); |
| | | claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName); |
| | | |
| | | // 接口返回信息 |
| | |
| | | Map<String, Object> claimsMap = new HashMap<String, Object>(); |
| | | claimsMap.put(SecurityConstants.USER_APPLET_KEY, token); |
| | | claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId); |
| | | claimsMap.put(SecurityConstants.USER_TYPE, "applet"); |
| | | claimsMap.put(SecurityConstants.DETAILS_USERNAME, name); |
| | | // 接口返回信息 |
| | | Map<String, Object> rspMap = new HashMap<String, Object>(); |
| | |
| | | <groupId>mysql</groupId> |
| | | <artifactId>mysql-connector-java</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- <dependency>--> |
| | | <!-- <groupId>org.springframework.boot</groupId>--> |
| | | <!-- <artifactId>spring-boot-starter-websocket</artifactId>--> |
| | | <!-- <optional>true</optional>--> |
| | | <!-- </dependency>--> |
| | | <!--hutool-all--> |
| | | <!-- <dependency>--> |
| | | <!-- <groupId>cn.hutool</groupId>--> |
| | | <!-- <artifactId>hutool-all</artifactId>--> |
| | | <!-- <version>5.0.3</version>--> |
| | | <!-- </dependency>--> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-api-account</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-api-system</artifactId> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | |
| | | |
| | | /** |
| | | * 网关启动程序 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) |
| | | public class RuoYiGatewayApplication |
| | | { |
| | | public static void main(String[] args) |
| | | { |
| | | SpringApplication.run(RuoYiGatewayApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 若依网关启动成功 ლ(´ڡ`ლ)゙ \n" + |
| | | " .-------. ____ __ \n" + |
| | | " | _ _ \\ \\ \\ / / \n" + |
| | | " | ( ' ) | \\ _. / ' \n" + |
| | | " |(_ o _) / _( )_ .' \n" + |
| | | " | (_,_).' __ ___(_ o _)' \n" + |
| | | " | |\\ \\ | || |(_,_)' \n" + |
| | | " | | \\ `' /| `-' / \n" + |
| | | " | | \\ / \\ / \n" + |
| | | " ''-' `'-' `-..-' "); |
| | | } |
| | | @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) |
| | | public class RuoYiGatewayApplication { |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(RuoYiGatewayApplication.class, args); |
| | | System.out.println("(♥◠‿◠)ノ゙ 若依网关启动成功 ლ(´ڡ`ლ)゙ \n" + |
| | | " .-------. ____ __ \n" + |
| | | " | _ _ \\ \\ \\ / / \n" + |
| | | " | ( ' ) | \\ _. / ' \n" + |
| | | " |(_ o _) / _( )_ .' \n" + |
| | | " | (_,_).' __ ___(_ o _)' \n" + |
| | | " | |\\ \\ | || |(_,_)' \n" + |
| | | " | | \\ `' /| `-' / \n" + |
| | | " | | \\ / \\ / \n" + |
| | | " ''-' `'-' `-..-' "); |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.gateway.config; |
| | | |
| | | import java.util.Properties; |
| | | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import com.google.code.kaptcha.impl.DefaultKaptcha; |
| | | import com.google.code.kaptcha.util.Config; |
| | | |
| | | import static com.google.code.kaptcha.Constants.*; |
| | | |
| | | /** |
| | | * 验证码配置 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Configuration |
| | | public class CaptchaConfig |
| | | { |
| | | @Bean(name = "captchaProducer") |
| | | public DefaultKaptcha getKaptchaBean() |
| | | { |
| | | DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); |
| | | Properties properties = new Properties(); |
| | | // 是否有边框 默认为true 我们可以自己设置yes,no |
| | | properties.setProperty(KAPTCHA_BORDER, "yes"); |
| | | // 验证码文本字符颜色 默认为Color.BLACK |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); |
| | | // 验证码图片宽度 默认为200 |
| | | properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); |
| | | // 验证码图片高度 默认为50 |
| | | properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); |
| | | // 验证码文本字符大小 默认为40 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); |
| | | // KAPTCHA_SESSION_KEY |
| | | properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); |
| | | // 验证码文本字符长度 默认为5 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); |
| | | // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); |
| | | // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy |
| | | properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); |
| | | Config config = new Config(properties); |
| | | defaultKaptcha.setConfig(config); |
| | | return defaultKaptcha; |
| | | } |
| | | |
| | | @Bean(name = "captchaProducerMath") |
| | | public DefaultKaptcha getKaptchaBeanMath() |
| | | { |
| | | DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); |
| | | Properties properties = new Properties(); |
| | | // 是否有边框 默认为true 我们可以自己设置yes,no |
| | | properties.setProperty(KAPTCHA_BORDER, "yes"); |
| | | // 边框颜色 默认为Color.BLACK |
| | | properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); |
| | | // 验证码文本字符颜色 默认为Color.BLACK |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); |
| | | // 验证码图片宽度 默认为200 |
| | | properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); |
| | | // 验证码图片高度 默认为50 |
| | | properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); |
| | | // 验证码文本字符大小 默认为40 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); |
| | | // KAPTCHA_SESSION_KEY |
| | | properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); |
| | | // 验证码文本生成器 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.gateway.config.KaptchaTextCreator"); |
| | | // 验证码文本字符间距 默认为2 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); |
| | | // 验证码文本字符长度 默认为5 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); |
| | | // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); |
| | | // 验证码噪点颜色 默认为Color.BLACK |
| | | properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); |
| | | // 干扰实现类 |
| | | properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); |
| | | // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy |
| | | properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); |
| | | Config config = new Config(properties); |
| | | defaultKaptcha.setConfig(config); |
| | | return defaultKaptcha; |
| | | } |
| | | public class CaptchaConfig { |
| | | @Bean(name = "captchaProducer") |
| | | public DefaultKaptcha getKaptchaBean() { |
| | | DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); |
| | | Properties properties = new Properties(); |
| | | // 是否有边框 默认为true 我们可以自己设置yes,no |
| | | properties.setProperty(KAPTCHA_BORDER, "yes"); |
| | | // 验证码文本字符颜色 默认为Color.BLACK |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); |
| | | // 验证码图片宽度 默认为200 |
| | | properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); |
| | | // 验证码图片高度 默认为50 |
| | | properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); |
| | | // 验证码文本字符大小 默认为40 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); |
| | | // KAPTCHA_SESSION_KEY |
| | | properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); |
| | | // 验证码文本字符长度 默认为5 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); |
| | | // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); |
| | | // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy |
| | | properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); |
| | | Config config = new Config(properties); |
| | | defaultKaptcha.setConfig(config); |
| | | return defaultKaptcha; |
| | | } |
| | | |
| | | @Bean(name = "captchaProducerMath") |
| | | public DefaultKaptcha getKaptchaBeanMath() { |
| | | DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); |
| | | Properties properties = new Properties(); |
| | | // 是否有边框 默认为true 我们可以自己设置yes,no |
| | | properties.setProperty(KAPTCHA_BORDER, "yes"); |
| | | // 边框颜色 默认为Color.BLACK |
| | | properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90"); |
| | | // 验证码文本字符颜色 默认为Color.BLACK |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue"); |
| | | // 验证码图片宽度 默认为200 |
| | | properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); |
| | | // 验证码图片高度 默认为50 |
| | | properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); |
| | | // 验证码文本字符大小 默认为40 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35"); |
| | | // KAPTCHA_SESSION_KEY |
| | | properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath"); |
| | | // 验证码文本生成器 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.ruoyi.gateway.config.KaptchaTextCreator"); |
| | | // 验证码文本字符间距 默认为2 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3"); |
| | | // 验证码文本字符长度 默认为5 |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6"); |
| | | // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) |
| | | properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); |
| | | // 验证码噪点颜色 默认为Color.BLACK |
| | | properties.setProperty(KAPTCHA_NOISE_COLOR, "white"); |
| | | // 干扰实现类 |
| | | properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); |
| | | // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy |
| | | properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); |
| | | Config config = new Config(properties); |
| | | defaultKaptcha.setConfig(config); |
| | | return defaultKaptcha; |
| | | } |
| | | } |
| | |
| | | |
| | | /** |
| | | * 网关限流配置 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Configuration |
| | | public class GatewayConfig |
| | | { |
| | | @Bean |
| | | @Order(Ordered.HIGHEST_PRECEDENCE) |
| | | public SentinelFallbackHandler sentinelGatewayExceptionHandler() |
| | | { |
| | | return new SentinelFallbackHandler(); |
| | | } |
| | | public class GatewayConfig { |
| | | @Bean |
| | | @Order(Ordered.HIGHEST_PRECEDENCE) |
| | | public SentinelFallbackHandler sentinelGatewayExceptionHandler() { |
| | | return new SentinelFallbackHandler(); |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.gateway.config; |
| | | |
| | | import java.util.Random; |
| | | |
| | | import com.google.code.kaptcha.text.impl.DefaultTextCreator; |
| | | |
| | | /** |
| | | * 验证码文本生成器 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class KaptchaTextCreator extends DefaultTextCreator |
| | | { |
| | | private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); |
| | | |
| | | @Override |
| | | public String getText() |
| | | { |
| | | Integer result = 0; |
| | | Random random = new Random(); |
| | | int x = random.nextInt(10); |
| | | int y = random.nextInt(10); |
| | | StringBuilder suChinese = new StringBuilder(); |
| | | int randomoperands = random.nextInt(3); |
| | | if (randomoperands == 0) |
| | | { |
| | | result = x * y; |
| | | suChinese.append(CNUMBERS[x]); |
| | | suChinese.append("*"); |
| | | suChinese.append(CNUMBERS[y]); |
| | | } |
| | | else if (randomoperands == 1) |
| | | { |
| | | if ((x != 0) && y % x == 0) |
| | | { |
| | | result = y / x; |
| | | suChinese.append(CNUMBERS[y]); |
| | | suChinese.append("/"); |
| | | suChinese.append(CNUMBERS[x]); |
| | | } |
| | | else |
| | | { |
| | | result = x + y; |
| | | suChinese.append(CNUMBERS[x]); |
| | | suChinese.append("+"); |
| | | suChinese.append(CNUMBERS[y]); |
| | | } |
| | | } |
| | | else if (randomoperands == 2) |
| | | { |
| | | if (x >= y) |
| | | { |
| | | result = x - y; |
| | | suChinese.append(CNUMBERS[x]); |
| | | suChinese.append("-"); |
| | | suChinese.append(CNUMBERS[y]); |
| | | } |
| | | else |
| | | { |
| | | result = y - x; |
| | | suChinese.append(CNUMBERS[y]); |
| | | suChinese.append("-"); |
| | | suChinese.append(CNUMBERS[x]); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | result = x + y; |
| | | suChinese.append(CNUMBERS[x]); |
| | | suChinese.append("+"); |
| | | suChinese.append(CNUMBERS[y]); |
| | | } |
| | | suChinese.append("=?@" + result); |
| | | return suChinese.toString(); |
| | | } |
| | | public class KaptchaTextCreator extends DefaultTextCreator { |
| | | private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); |
| | | |
| | | @Override |
| | | public String getText() { |
| | | Integer result = 0; |
| | | Random random = new Random(); |
| | | int x = random.nextInt(10); |
| | | int y = random.nextInt(10); |
| | | StringBuilder suChinese = new StringBuilder(); |
| | | int randomoperands = random.nextInt(3); |
| | | if (randomoperands == 0) { |
| | | result = x * y; |
| | | suChinese.append(CNUMBERS[x]); |
| | | suChinese.append("*"); |
| | | suChinese.append(CNUMBERS[y]); |
| | | } else if (randomoperands == 1) { |
| | | if ((x != 0) && y % x == 0) { |
| | | result = y / x; |
| | | suChinese.append(CNUMBERS[y]); |
| | | suChinese.append("/"); |
| | | suChinese.append(CNUMBERS[x]); |
| | | } else { |
| | | result = x + y; |
| | | suChinese.append(CNUMBERS[x]); |
| | | suChinese.append("+"); |
| | | suChinese.append(CNUMBERS[y]); |
| | | } |
| | | } else if (randomoperands == 2) { |
| | | if (x >= y) { |
| | | result = x - y; |
| | | suChinese.append(CNUMBERS[x]); |
| | | suChinese.append("-"); |
| | | suChinese.append(CNUMBERS[y]); |
| | | } else { |
| | | result = y - x; |
| | | suChinese.append(CNUMBERS[y]); |
| | | suChinese.append("-"); |
| | | suChinese.append(CNUMBERS[x]); |
| | | } |
| | | } else { |
| | | result = x + y; |
| | | suChinese.append(CNUMBERS[x]); |
| | | suChinese.append("+"); |
| | | suChinese.append(CNUMBERS[y]); |
| | | } |
| | | suChinese.append("=?@" + result); |
| | | return suChinese.toString(); |
| | | } |
| | | } |
| | |
| | | * @author ruoyi |
| | | */ |
| | | @Configuration |
| | | public class RouterFunctionConfiguration |
| | | { |
| | | public class RouterFunctionConfiguration { |
| | | |
| | | /** |
| | | * 这里为支持的请求头,如果有自定义的header字段请自己添加 |
| | | */ |
| | | private static final String ALLOWED_HEADERS = "X-Requested-With, Content-Type, Authorization, credential, X-XSRF-TOKEN, token, username, client, request-origion, sign, nonce_str"; |
| | | private static final String ALLOWED_METHODS = "GET,POST,PUT,DELETE,OPTIONS,HEAD"; |
| | | private static final String ALLOWED_ORIGIN = "*"; |
| | | private static final String ALLOWED_EXPOSE = "*"; |
| | | private static final String MAX_AGE = "18000L"; |
| | | /** |
| | | * 这里为支持的请求头,如果有自定义的header字段请自己添加 |
| | | */ |
| | | private static final String ALLOWED_HEADERS = "X-Requested-With, Content-Type, Authorization, credential, X-XSRF-TOKEN, token, username, client, request-origion, sign, nonce_str, timestamp"; |
| | | private static final String ALLOWED_METHODS = "GET,POST,PUT,DELETE,OPTIONS,HEAD"; |
| | | private static final String ALLOWED_ORIGIN = "*"; |
| | | private static final String ALLOWED_EXPOSE = "*"; |
| | | private static final String MAX_AGE = "18000L"; |
| | | |
| | | @Autowired |
| | | private ValidateCodeHandler validateCodeHandler; |
| | | @Autowired |
| | | private ValidateCodeHandler validateCodeHandler; |
| | | |
| | | @SuppressWarnings("rawtypes") |
| | | @Bean |
| | | public RouterFunction routerFunction() |
| | | { |
| | | return RouterFunctions.route( |
| | | RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), |
| | | validateCodeHandler); |
| | | } |
| | | @SuppressWarnings("rawtypes") |
| | | @Bean |
| | | public RouterFunction routerFunction() { |
| | | return RouterFunctions.route( |
| | | RequestPredicates.GET("/code").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), |
| | | validateCodeHandler); |
| | | } |
| | | |
| | | /** |
| | | * 跨域配置 |
| | | */ |
| | | @Bean |
| | | public WebFilter corsFilter() |
| | | { |
| | | return (ServerWebExchange ctx, WebFilterChain chain) -> { |
| | | ServerHttpRequest request = ctx.getRequest(); |
| | | if (CorsUtils.isCorsRequest(request)) |
| | | { |
| | | ServerHttpResponse response = ctx.getResponse(); |
| | | HttpHeaders headers = response.getHeaders(); |
| | | headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS); |
| | | headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS); |
| | | headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN); |
| | | headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE); |
| | | headers.add("Access-Control-Max-Age", MAX_AGE); |
| | | headers.add("Access-Control-Allow-Credentials", "true"); |
| | | if (request.getMethod() == HttpMethod.OPTIONS) |
| | | { |
| | | response.setStatusCode(HttpStatus.OK); |
| | | return Mono.empty(); |
| | | } |
| | | } |
| | | return chain.filter(ctx); |
| | | }; |
| | | } |
| | | /** |
| | | * 跨域配置 |
| | | */ |
| | | @Bean |
| | | public WebFilter corsFilter() { |
| | | return (ServerWebExchange ctx, WebFilterChain chain) -> { |
| | | ServerHttpRequest request = ctx.getRequest(); |
| | | if (CorsUtils.isCorsRequest(request)) { |
| | | ServerHttpResponse response = ctx.getResponse(); |
| | | HttpHeaders headers = response.getHeaders(); |
| | | headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS); |
| | | headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS); |
| | | headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN); |
| | | headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE); |
| | | headers.add("Access-Control-Max-Age", MAX_AGE); |
| | | headers.add("Access-Control-Allow-Credentials", "true"); |
| | | if (request.getMethod() == HttpMethod.OPTIONS) { |
| | | response.setStatusCode(HttpStatus.OK); |
| | | return Mono.empty(); |
| | | } |
| | | } |
| | | return chain.filter(ctx); |
| | | }; |
| | | } |
| | | } |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.cloud.gateway.config.GatewayProperties; |
| | | import org.springframework.cloud.gateway.route.RouteLocator; |
| | |
| | | |
| | | /** |
| | | * 聚合系统接口 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigurer |
| | | { |
| | | /** |
| | | * Swagger2默认的url后缀 |
| | | */ |
| | | public static final String SWAGGER2URL = "/v2/api-docs"; |
| | | |
| | | /** |
| | | * 网关路由 |
| | | */ |
| | | @Lazy |
| | | @Autowired |
| | | private RouteLocator routeLocator; |
| | | |
| | | @Autowired |
| | | private GatewayProperties gatewayProperties; |
| | | |
| | | /** |
| | | * 聚合其他服务接口 |
| | | * |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<SwaggerResource> get() |
| | | { |
| | | List<SwaggerResource> resourceList = new ArrayList<>(); |
| | | List<String> routes = new ArrayList<>(); |
| | | // 获取网关中配置的route |
| | | routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); |
| | | gatewayProperties.getRoutes().stream() |
| | | .filter(routeDefinition -> routes |
| | | .contains(routeDefinition.getId())) |
| | | .forEach(routeDefinition -> routeDefinition.getPredicates().stream() |
| | | .filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName())) |
| | | .filter(predicateDefinition -> !"ruoyi-auth".equalsIgnoreCase(routeDefinition.getId())) |
| | | .forEach(predicateDefinition -> resourceList |
| | | .add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs() |
| | | .get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", SWAGGER2URL))))); |
| | | return resourceList; |
| | | } |
| | | |
| | | private SwaggerResource swaggerResource(String name, String location) |
| | | { |
| | | SwaggerResource swaggerResource = new SwaggerResource(); |
| | | swaggerResource.setName(name); |
| | | swaggerResource.setLocation(location); |
| | | swaggerResource.setSwaggerVersion("2.0"); |
| | | return swaggerResource; |
| | | } |
| | | |
| | | @Override |
| | | public void addResourceHandlers(ResourceHandlerRegistry registry) |
| | | { |
| | | /** swagger-ui 地址 */ |
| | | registry.addResourceHandler("/swagger-ui/**","*/doc.html") |
| | | .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); |
| | | } |
| | | public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigurer { |
| | | /** |
| | | * Swagger2默认的url后缀 |
| | | */ |
| | | public static final String SWAGGER2URL = "/v2/api-docs"; |
| | | |
| | | /** |
| | | * 网关路由 |
| | | */ |
| | | @Lazy |
| | | @Autowired |
| | | private RouteLocator routeLocator; |
| | | |
| | | @Autowired |
| | | private GatewayProperties gatewayProperties; |
| | | |
| | | /** |
| | | * 聚合其他服务接口 |
| | | * |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<SwaggerResource> get() { |
| | | List<SwaggerResource> resourceList = new ArrayList<>(); |
| | | List<String> routes = new ArrayList<>(); |
| | | // 获取网关中配置的route |
| | | routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); |
| | | gatewayProperties.getRoutes().stream() |
| | | .filter(routeDefinition -> routes |
| | | .contains(routeDefinition.getId())) |
| | | .forEach(routeDefinition -> routeDefinition.getPredicates().stream() |
| | | .filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName())) |
| | | .filter(predicateDefinition -> !"ruoyi-auth".equalsIgnoreCase(routeDefinition.getId())) |
| | | .forEach(predicateDefinition -> resourceList |
| | | .add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs() |
| | | .get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", SWAGGER2URL))))); |
| | | return resourceList; |
| | | } |
| | | |
| | | private SwaggerResource swaggerResource(String name, String location) { |
| | | SwaggerResource swaggerResource = new SwaggerResource(); |
| | | swaggerResource.setName(name); |
| | | swaggerResource.setLocation(location); |
| | | swaggerResource.setSwaggerVersion("2.0"); |
| | | return swaggerResource; |
| | | } |
| | | |
| | | @Override |
| | | public void addResourceHandlers(ResourceHandlerRegistry registry) { |
| | | /** swagger-ui 地址 */ |
| | | registry.addResourceHandler("/swagger-ui/**", "*/doc.html") |
| | | .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); |
| | | } |
| | | } |
| | |
| | | |
| | | /** |
| | | * 验证码配置 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Configuration |
| | | @RefreshScope |
| | | @ConfigurationProperties(prefix = "security.captcha") |
| | | public class CaptchaProperties |
| | | { |
| | | /** |
| | | * 验证码开关 |
| | | */ |
| | | private Boolean enabled; |
| | | |
| | | /** |
| | | * 验证码类型(math 数组计算 char 字符) |
| | | */ |
| | | private String type; |
| | | |
| | | public Boolean getEnabled() |
| | | { |
| | | return enabled; |
| | | } |
| | | |
| | | public void setEnabled(Boolean enabled) |
| | | { |
| | | this.enabled = enabled; |
| | | } |
| | | |
| | | public String getType() |
| | | { |
| | | return type; |
| | | } |
| | | |
| | | public void setType(String type) |
| | | { |
| | | this.type = type; |
| | | } |
| | | public class CaptchaProperties { |
| | | /** |
| | | * 验证码开关 |
| | | */ |
| | | private Boolean enabled; |
| | | |
| | | /** |
| | | * 验证码类型(math 数组计算 char 字符) |
| | | */ |
| | | private String type; |
| | | |
| | | public Boolean getEnabled() { |
| | | return enabled; |
| | | } |
| | | |
| | | public void setEnabled(Boolean enabled) { |
| | | this.enabled = enabled; |
| | | } |
| | | |
| | | public String getType() { |
| | | return type; |
| | | } |
| | | |
| | | public void setType(String type) { |
| | | this.type = type; |
| | | } |
| | | } |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.cloud.context.config.annotation.RefreshScope; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * 放行白名单配置 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Configuration |
| | | @RefreshScope |
| | | @ConfigurationProperties(prefix = "security.ignore") |
| | | public class IgnoreWhiteProperties |
| | | { |
| | | /** |
| | | * 放行白名单配置,网关不校验此处的白名单 |
| | | */ |
| | | private List<String> whites = new ArrayList<>(); |
| | | |
| | | public List<String> getWhites() |
| | | { |
| | | return whites; |
| | | } |
| | | |
| | | public void setWhites(List<String> whites) |
| | | { |
| | | this.whites = whites; |
| | | } |
| | | public class IgnoreWhiteProperties { |
| | | /** |
| | | * 放行白名单配置,网关不校验此处的白名单 |
| | | */ |
| | | private List<String> whites = new ArrayList<>(); |
| | | |
| | | public List<String> getWhites() { |
| | | return whites; |
| | | } |
| | | |
| | | public void setWhites(List<String> whites) { |
| | | this.whites = whites; |
| | | } |
| | | } |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.cloud.context.config.annotation.RefreshScope; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * XSS跨站脚本配置 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Configuration |
| | | @RefreshScope |
| | | @ConfigurationProperties(prefix = "security.xss") |
| | | public class XssProperties |
| | | { |
| | | /** |
| | | * Xss开关 |
| | | */ |
| | | private Boolean enabled; |
| | | |
| | | /** |
| | | * 排除路径 |
| | | */ |
| | | private List<String> excludeUrls = new ArrayList<>(); |
| | | |
| | | public Boolean getEnabled() |
| | | { |
| | | return enabled; |
| | | } |
| | | |
| | | public void setEnabled(Boolean enabled) |
| | | { |
| | | this.enabled = enabled; |
| | | } |
| | | |
| | | public List<String> getExcludeUrls() |
| | | { |
| | | return excludeUrls; |
| | | } |
| | | |
| | | public void setExcludeUrls(List<String> excludeUrls) |
| | | { |
| | | this.excludeUrls = excludeUrls; |
| | | } |
| | | public class XssProperties { |
| | | /** |
| | | * Xss开关 |
| | | */ |
| | | private Boolean enabled; |
| | | |
| | | /** |
| | | * 排除路径 |
| | | */ |
| | | private List<String> excludeUrls = new ArrayList<>(); |
| | | |
| | | public Boolean getEnabled() { |
| | | return enabled; |
| | | } |
| | | |
| | | public void setEnabled(Boolean enabled) { |
| | | this.enabled = enabled; |
| | | } |
| | | |
| | | public List<String> getExcludeUrls() { |
| | | return excludeUrls; |
| | | } |
| | | |
| | | public void setExcludeUrls(List<String> excludeUrls) { |
| | | this.excludeUrls = excludeUrls; |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.gateway.filter; |
| | | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.apache.commons.codec.binary.Base64; |
| | | import com.ruoyi.account.api.feignClient.AppUserClient; |
| | | import com.ruoyi.account.api.model.TAppUser; |
| | | import com.ruoyi.system.api.domain.SysUser; |
| | | import com.ruoyi.system.api.feignClient.SysUserClient; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.cloud.gateway.filter.GatewayFilterChain; |
| | | import org.springframework.cloud.gateway.filter.GlobalFilter; |
| | | import org.springframework.core.Ordered; |
| | | import org.springframework.core.io.buffer.DataBuffer; |
| | | import org.springframework.http.HttpHeaders; |
| | | import org.springframework.http.server.reactive.ServerHttpRequest; |
| | | import org.springframework.http.server.reactive.ServerHttpRequestDecorator; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.web.server.ServerWebExchange; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | |
| | | import com.ruoyi.common.redis.service.RedisService; |
| | | import com.ruoyi.gateway.config.properties.IgnoreWhiteProperties; |
| | | import io.jsonwebtoken.Claims; |
| | | import reactor.core.publisher.Flux; |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | import java.util.concurrent.atomic.AtomicReference; |
| | | import javax.annotation.Resource; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | |
| | | /** |
| | | * 网关鉴权 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class AuthFilter implements GlobalFilter, Ordered { |
| | | private static final Logger log = LoggerFactory.getLogger(AuthFilter.class); |
| | | |
| | | // 排除过滤的 uri 地址,nacos自行添加 |
| | | @Autowired |
| | | private IgnoreWhiteProperties ignoreWhite; |
| | | |
| | | @Autowired |
| | | private RedisService redisService; |
| | | |
| | | |
| | | @Override |
| | | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| | | ServerHttpRequest request = exchange.getRequest(); |
| | | ServerHttpRequest.Builder mutate = request.mutate(); |
| | | |
| | | String url = request.getURI().getPath(); |
| | | // 跳过不需要验证的路径 |
| | | if (StringUtils.matches(url, ignoreWhite.getWhites())) { |
| | | return chain.filter(exchange); |
| | | } |
| | | String token = getToken(request); |
| | | if (StringUtils.isEmpty(token)) { |
| | | return unauthorizedResponse(exchange, "令牌不能为空"); |
| | | } |
| | | Claims claims = JwtUtils.parseToken(token); |
| | | if (claims == null) { |
| | | return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); |
| | | } |
| | | String userkey = JwtUtils.getUserKey(claims); |
| | | boolean islogin = redisService.hasKey(getTokenKey(userkey)); |
| | | if (!islogin) { |
| | | return unauthorizedResponse(exchange, "登录状态已过期"); |
| | | } |
| | | String userid = JwtUtils.getUserId(claims); |
| | | String username = JwtUtils.getUserName(claims); |
| | | if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) { |
| | | return unauthorizedResponse(exchange, "令牌验证失败"); |
| | | } |
| | | |
| | | // 设置用户信息到请求 |
| | | addHeader(mutate, SecurityConstants.USER_KEY, userkey); |
| | | addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid); |
| | | addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username); |
| | | // 内部请求来源参数清除 |
| | | removeHeader(mutate, SecurityConstants.FROM_SOURCE); |
| | | return chain.filter(exchange.mutate().request(mutate.build()).build()); |
| | | } |
| | | |
| | | private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) { |
| | | if (value == null) { |
| | | return; |
| | | } |
| | | String valueStr = value.toString(); |
| | | String valueEncode = ServletUtils.urlEncode(valueStr); |
| | | mutate.header(name, valueEncode); |
| | | } |
| | | |
| | | private void removeHeader(ServerHttpRequest.Builder mutate, String name) { |
| | | mutate.headers(httpHeaders -> httpHeaders.remove(name)).build(); |
| | | } |
| | | |
| | | private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg) { |
| | | log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath()); |
| | | return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED); |
| | | } |
| | | |
| | | /** |
| | | * 获取缓存key |
| | | */ |
| | | private String getTokenKey(String token) |
| | | { |
| | | return CacheConstants.LOGIN_TOKEN_KEY + token; |
| | | } |
| | | |
| | | /** |
| | | * 获取请求token |
| | | */ |
| | | private String getToken(ServerHttpRequest request) { |
| | | String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION); |
| | | // 如果前端设置了令牌前缀,则裁剪掉前缀 |
| | | if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) |
| | | { |
| | | token = token.replaceFirst(TokenConstants.PREFIX, StringUtils.EMPTY); |
| | | } |
| | | return token; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public int getOrder() |
| | | { |
| | | return -300; |
| | | } |
| | | private static final Logger log = LoggerFactory.getLogger(AuthFilter.class); |
| | | |
| | | // 排除过滤的 uri 地址,nacos自行添加 |
| | | @Autowired |
| | | private IgnoreWhiteProperties ignoreWhite; |
| | | |
| | | @Autowired |
| | | private RedisService redisService; |
| | | |
| | | @Resource |
| | | private AppUserClient appUserClient; |
| | | |
| | | @Resource |
| | | private SysUserClient sysUserClient; |
| | | |
| | | |
| | | |
| | | @Override |
| | | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| | | ServerHttpRequest request = exchange.getRequest(); |
| | | ServerHttpRequest.Builder mutate = request.mutate(); |
| | | |
| | | String url = request.getURI().getPath(); |
| | | // 跳过不需要验证的路径 |
| | | if (StringUtils.matches(url, ignoreWhite.getWhites())) { |
| | | return chain.filter(exchange); |
| | | } |
| | | //防抖校验 |
| | | try { |
| | | antiShake(request); |
| | | }catch (Exception e){ |
| | | log.error("[重复提交]请求路径:{}", exchange.getRequest().getPath()); |
| | | return ServletUtils.webFluxResponseWriter(exchange.getResponse(), e.getMessage(), HttpStatus.SUCCESS); |
| | | } |
| | | |
| | | //校验账户是否有效 |
| | | try { |
| | | verifyToken(request); |
| | | verifyAccount(request); |
| | | }catch (Exception e){ |
| | | return unauthorizedResponse(exchange, e.getMessage()); |
| | | } |
| | | String token = getToken(request); |
| | | Claims claims = JwtUtils.parseToken(token); |
| | | String userkey = JwtUtils.getUserKey(claims); |
| | | String userid = JwtUtils.getUserId(claims); |
| | | String username = JwtUtils.getUserName(claims); |
| | | |
| | | // 设置用户信息到请求 |
| | | addHeader(mutate, SecurityConstants.USER_KEY, userkey); |
| | | addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid); |
| | | addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username); |
| | | // 内部请求来源参数清除 |
| | | removeHeader(mutate, SecurityConstants.FROM_SOURCE); |
| | | return chain.filter(exchange.mutate().request(mutate.build()).build()); |
| | | } |
| | | |
| | | private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) { |
| | | if (value == null) { |
| | | return; |
| | | } |
| | | String valueStr = value.toString(); |
| | | String valueEncode = ServletUtils.urlEncode(valueStr); |
| | | mutate.header(name, valueEncode); |
| | | } |
| | | |
| | | private void removeHeader(ServerHttpRequest.Builder mutate, String name) { |
| | | mutate.headers(httpHeaders -> httpHeaders.remove(name)).build(); |
| | | } |
| | | |
| | | private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg) { |
| | | log.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath()); |
| | | return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED); |
| | | } |
| | | |
| | | /** |
| | | * 获取缓存key |
| | | */ |
| | | private String getTokenKey(String token) { |
| | | return CacheConstants.LOGIN_TOKEN_KEY + token; |
| | | } |
| | | |
| | | /** |
| | | * 获取请求token |
| | | */ |
| | | private String getToken(ServerHttpRequest request) { |
| | | String token = request.getHeaders().getFirst(TokenConstants.AUTHENTICATION); |
| | | // 如果前端设置了令牌前缀,则裁剪掉前缀 |
| | | if (StringUtils.isNotEmpty(token) && token.startsWith(TokenConstants.PREFIX)) { |
| | | token = token.replaceFirst(TokenConstants.PREFIX, StringUtils.EMPTY); |
| | | } |
| | | return token; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 防抖处理 |
| | | */ |
| | | public void antiShake(ServerHttpRequest request) throws Exception{ |
| | | HttpHeaders headers = request.getHeaders(); |
| | | String client = headers.getFirst("client"); |
| | | String timestamp = headers.getFirst("timestamp"); |
| | | String url = request.getURI().getPath(); |
| | | Map<String, Object> cacheMap = redisService.getCacheMap(client); |
| | | if(null == cacheMap){ |
| | | cacheMap = new HashMap<>(); |
| | | cacheMap.put(url, timestamp); |
| | | redisService.setCacheMap(client, cacheMap); |
| | | }else{ |
| | | Object o = cacheMap.get(url); |
| | | if(null == o){ |
| | | cacheMap.put(url, timestamp); |
| | | }else{ |
| | | Long old_timestamp = Long.valueOf(o.toString()); |
| | | Long new_timestamp = Long.valueOf(timestamp); |
| | | //两个请求时间差小于1秒,判定为重复提交 |
| | | if((new_timestamp - old_timestamp) <= 1000){ |
| | | throw new RuntimeException("重复提交"); |
| | | }else{ |
| | | cacheMap.put(url, timestamp); |
| | | } |
| | | } |
| | | redisService.setCacheMap(client, cacheMap); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 验证token |
| | | * @param request |
| | | * @throws Exception |
| | | */ |
| | | public void verifyToken(ServerHttpRequest request) throws Exception{ |
| | | String token = getToken(request); |
| | | if (StringUtils.isEmpty(token)) { |
| | | throw new RuntimeException("令牌不能为空"); |
| | | } |
| | | Claims claims = JwtUtils.parseToken(token); |
| | | if (claims == null) { |
| | | throw new RuntimeException("令牌已过期或验证不正确!"); |
| | | } |
| | | String userkey = JwtUtils.getUserKey(claims); |
| | | boolean islogin = redisService.hasKey(getTokenKey(userkey)); |
| | | if (!islogin) { |
| | | throw new RuntimeException("登录状态已过期"); |
| | | } |
| | | String userid = JwtUtils.getUserId(claims); |
| | | String username = JwtUtils.getUserName(claims); |
| | | if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username)) { |
| | | throw new RuntimeException("令牌验证失败"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 校验账户是否有效 |
| | | * @param request |
| | | * @throws Exception |
| | | */ |
| | | public void verifyAccount(ServerHttpRequest request) throws Exception{ |
| | | String token = getToken(request); |
| | | Claims claims = JwtUtils.parseToken(token); |
| | | String userid = JwtUtils.getUserId(claims); |
| | | String userType = JwtUtils.getUserType(claims); |
| | | //管理后台用户 |
| | | if ("system".equals(userType)) { |
| | | SysUser sysUser = sysUserClient.getSysUser(Long.valueOf(userid)).getData(); |
| | | if(null == sysUser || "2".equals(sysUser.getDelFlag())){ |
| | | throw new RuntimeException("无效的账户"); |
| | | } |
| | | if("1".equals(sysUser.getStatus())){ |
| | | throw new RuntimeException("账户已被停用,请联系系统管理员!"); |
| | | } |
| | | } |
| | | //小程序用户 |
| | | if ("applet".equals(userType)) { |
| | | TAppUser appUser = appUserClient.getUserById(Long.valueOf(userid)).getData(); |
| | | if(null == appUser || appUser.getDelFlag() || 3 == appUser.getStatus()){ |
| | | throw new RuntimeException("无效的账户"); |
| | | } |
| | | if(2 == appUser.getStatus()){ |
| | | throw new RuntimeException("账户已被冻结,请联系系统管理员!"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public int getOrder() { |
| | | return -300; |
| | | } |
| | | } |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.regex.Pattern; |
| | | |
| | | import org.springframework.cloud.gateway.filter.GatewayFilter; |
| | | import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | |
| | | /** |
| | | * 黑名单过滤器 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class BlackListUrlFilter extends AbstractGatewayFilterFactory<BlackListUrlFilter.Config> |
| | | { |
| | | @Override |
| | | public GatewayFilter apply(Config config) |
| | | { |
| | | return (exchange, chain) -> { |
| | | |
| | | String url = exchange.getRequest().getURI().getPath(); |
| | | if (config.matchBlacklist(url)) |
| | | { |
| | | return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求地址不允许访问"); |
| | | } |
| | | |
| | | return chain.filter(exchange); |
| | | }; |
| | | } |
| | | |
| | | public BlackListUrlFilter() |
| | | { |
| | | super(Config.class); |
| | | } |
| | | |
| | | public static class Config |
| | | { |
| | | private List<String> blacklistUrl; |
| | | |
| | | private List<Pattern> blacklistUrlPattern = new ArrayList<>(); |
| | | |
| | | public boolean matchBlacklist(String url) |
| | | { |
| | | return !blacklistUrlPattern.isEmpty() && blacklistUrlPattern.stream().anyMatch(p -> p.matcher(url).find()); |
| | | } |
| | | |
| | | public List<String> getBlacklistUrl() |
| | | { |
| | | return blacklistUrl; |
| | | } |
| | | |
| | | public void setBlacklistUrl(List<String> blacklistUrl) |
| | | { |
| | | this.blacklistUrl = blacklistUrl; |
| | | this.blacklistUrlPattern.clear(); |
| | | this.blacklistUrl.forEach(url -> { |
| | | this.blacklistUrlPattern.add(Pattern.compile(url.replaceAll("\\*\\*", "(.*?)"), Pattern.CASE_INSENSITIVE)); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | public class BlackListUrlFilter extends AbstractGatewayFilterFactory<BlackListUrlFilter.Config> { |
| | | public BlackListUrlFilter() { |
| | | super(Config.class); |
| | | } |
| | | |
| | | @Override |
| | | public GatewayFilter apply(Config config) { |
| | | return (exchange, chain) -> { |
| | | |
| | | String url = exchange.getRequest().getURI().getPath(); |
| | | if (config.matchBlacklist(url)) { |
| | | return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求地址不允许访问"); |
| | | } |
| | | |
| | | return chain.filter(exchange); |
| | | }; |
| | | } |
| | | |
| | | public static class Config { |
| | | private List<String> blacklistUrl; |
| | | |
| | | private List<Pattern> blacklistUrlPattern = new ArrayList<>(); |
| | | |
| | | public boolean matchBlacklist(String url) { |
| | | return !blacklistUrlPattern.isEmpty() && blacklistUrlPattern.stream().anyMatch(p -> p.matcher(url).find()); |
| | | } |
| | | |
| | | public List<String> getBlacklistUrl() { |
| | | return blacklistUrl; |
| | | } |
| | | |
| | | public void setBlacklistUrl(List<String> blacklistUrl) { |
| | | this.blacklistUrl = blacklistUrl; |
| | | this.blacklistUrlPattern.clear(); |
| | | this.blacklistUrl.forEach(url -> { |
| | | this.blacklistUrlPattern.add(Pattern.compile(url.replaceAll("\\*\\*", "(.*?)"), Pattern.CASE_INSENSITIVE)); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | import org.springframework.cloud.gateway.filter.GatewayFilter; |
| | | import org.springframework.cloud.gateway.filter.GatewayFilterChain; |
| | | import org.springframework.cloud.gateway.filter.OrderedGatewayFilter; |
| | |
| | | |
| | | /** |
| | | * 获取body请求数据(解决流不能重复读取问题) |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class CacheRequestFilter extends AbstractGatewayFilterFactory<CacheRequestFilter.Config> |
| | | { |
| | | public CacheRequestFilter() |
| | | { |
| | | super(Config.class); |
| | | } |
| | | |
| | | @Override |
| | | public String name() |
| | | { |
| | | return "CacheRequestFilter"; |
| | | } |
| | | |
| | | @Override |
| | | public GatewayFilter apply(Config config) |
| | | { |
| | | CacheRequestGatewayFilter cacheRequestGatewayFilter = new CacheRequestGatewayFilter(); |
| | | Integer order = config.getOrder(); |
| | | if (order == null) |
| | | { |
| | | return cacheRequestGatewayFilter; |
| | | } |
| | | return new OrderedGatewayFilter(cacheRequestGatewayFilter, order); |
| | | } |
| | | |
| | | public static class CacheRequestGatewayFilter implements GatewayFilter |
| | | { |
| | | @Override |
| | | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) |
| | | { |
| | | // GET DELETE 不过滤 |
| | | HttpMethod method = exchange.getRequest().getMethod(); |
| | | if (method == null || method == HttpMethod.GET || method == HttpMethod.DELETE) |
| | | { |
| | | return chain.filter(exchange); |
| | | } |
| | | return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange, (serverHttpRequest) -> { |
| | | if (serverHttpRequest == exchange.getRequest()) |
| | | { |
| | | return chain.filter(exchange); |
| | | } |
| | | return chain.filter(exchange.mutate().request(serverHttpRequest).build()); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public List<String> shortcutFieldOrder() |
| | | { |
| | | return Collections.singletonList("order"); |
| | | } |
| | | |
| | | static class Config |
| | | { |
| | | private Integer order; |
| | | |
| | | public Integer getOrder() |
| | | { |
| | | return order; |
| | | } |
| | | |
| | | public void setOrder(Integer order) |
| | | { |
| | | this.order = order; |
| | | } |
| | | } |
| | | public class CacheRequestFilter extends AbstractGatewayFilterFactory<CacheRequestFilter.Config> { |
| | | public CacheRequestFilter() { |
| | | super(Config.class); |
| | | } |
| | | |
| | | @Override |
| | | public String name() { |
| | | return "CacheRequestFilter"; |
| | | } |
| | | |
| | | @Override |
| | | public GatewayFilter apply(Config config) { |
| | | CacheRequestGatewayFilter cacheRequestGatewayFilter = new CacheRequestGatewayFilter(); |
| | | Integer order = config.getOrder(); |
| | | if (order == null) { |
| | | return cacheRequestGatewayFilter; |
| | | } |
| | | return new OrderedGatewayFilter(cacheRequestGatewayFilter, order); |
| | | } |
| | | |
| | | @Override |
| | | public List<String> shortcutFieldOrder() { |
| | | return Collections.singletonList("order"); |
| | | } |
| | | |
| | | public static class CacheRequestGatewayFilter implements GatewayFilter { |
| | | @Override |
| | | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| | | // GET DELETE 不过滤 |
| | | HttpMethod method = exchange.getRequest().getMethod(); |
| | | if (method == null || method == HttpMethod.GET || method == HttpMethod.DELETE) { |
| | | return chain.filter(exchange); |
| | | } |
| | | return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange, (serverHttpRequest) -> { |
| | | if (serverHttpRequest == exchange.getRequest()) { |
| | | return chain.filter(exchange); |
| | | } |
| | | return chain.filter(exchange.mutate().request(serverHttpRequest).build()); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | static class Config { |
| | | private Integer order; |
| | | |
| | | public Integer getOrder() { |
| | | return order; |
| | | } |
| | | |
| | | public void setOrder(Integer order) { |
| | | this.order = order; |
| | | } |
| | | } |
| | | } |
| | |
| | | import javax.crypto.spec.SecretKeySpec; |
| | | |
| | | public class HMACSHA1 { |
| | | |
| | | |
| | | private static final String MAC_NAME = "HmacSHA1"; |
| | | private static final String ENCODING = "UTF-8"; |
| | | |
| | | |
| | | /** |
| | | * 使用 HMAC-SHA1 签名方法对对encryptText进行签名 |
| | | * |
| | | * @param encryptText |
| | | * 被签名的字符串 |
| | | * @param encryptKey |
| | | * 密钥 |
| | | * |
| | | * @param encryptText 被签名的字符串 |
| | | * @param encryptKey 密钥 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | |
| | | // 生成一个指定 Mac 算法 的 Mac 对象 |
| | | // 用给定密钥初始化 Mac 对象 |
| | | mac.init(secretKey); |
| | | |
| | | |
| | | byte[] text = encryptText.getBytes(ENCODING); |
| | | // 完成 Mac 操作 |
| | | return mac.doFinal(text); |
| | |
| | | */ |
| | | @Component |
| | | public class RequestParamGlobalFilter implements GlobalFilter, Ordered { |
| | | |
| | | |
| | | |
| | | @Override |
| | | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| | | ServerHttpRequestDecorator httpRequestDecorator = requestDecorator(exchange); |
| | | return chain.filter(exchange.mutate().request(httpRequestDecorator).build()); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | private ServerHttpRequestDecorator requestDecorator(ServerWebExchange exchange) { |
| | | ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) { |
| | | @Override |
| | | public Flux<DataBuffer> getBody() { |
| | | Flux<DataBuffer> body = super.getBody(); |
| | | return body.buffer().map(dataBuffers -> { |
| | | DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory(); |
| | | DataBuffer join = dataBufferFactory.join(dataBuffers); |
| | | byte[] content = new byte[join.readableByteCount()]; |
| | | join.read(content); |
| | | DataBufferUtils.release(join); |
| | | String bodyStr = new String(content, StandardCharsets.UTF_8); |
| | | // 转成字节 |
| | | byte[] bytes = bodyStr.getBytes(); |
| | | NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT); |
| | | DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length); |
| | | buffer.write(bytes); |
| | | return buffer; |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | public HttpHeaders getHeaders() { |
| | | HttpHeaders httpHeaders = new HttpHeaders(); |
| | | httpHeaders.putAll(super.getHeaders()); |
| | | // 由于修改了请求体的body,导致content-length长度不确定,因此需要删除原先的content-length |
| | | httpHeaders.remove(HttpHeaders.CONTENT_LENGTH); |
| | | httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); |
| | | return httpHeaders; |
| | | } |
| | | |
| | | }; |
| | | return serverHttpRequestDecorator; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public int getOrder() |
| | | { |
| | | return HIGHEST_PRECEDENCE; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| | | ServerHttpRequestDecorator httpRequestDecorator = requestDecorator(exchange); |
| | | return chain.filter(exchange.mutate().request(httpRequestDecorator).build()); |
| | | } |
| | | |
| | | |
| | | private ServerHttpRequestDecorator requestDecorator(ServerWebExchange exchange) { |
| | | ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) { |
| | | @Override |
| | | public Flux<DataBuffer> getBody() { |
| | | Flux<DataBuffer> body = super.getBody(); |
| | | return body.buffer().map(dataBuffers -> { |
| | | DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory(); |
| | | DataBuffer join = dataBufferFactory.join(dataBuffers); |
| | | byte[] content = new byte[join.readableByteCount()]; |
| | | join.read(content); |
| | | DataBufferUtils.release(join); |
| | | String bodyStr = new String(content, StandardCharsets.UTF_8); |
| | | // 转成字节 |
| | | byte[] bytes = bodyStr.getBytes(); |
| | | NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT); |
| | | DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length); |
| | | buffer.write(bytes); |
| | | return buffer; |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | public HttpHeaders getHeaders() { |
| | | HttpHeaders httpHeaders = new HttpHeaders(); |
| | | httpHeaders.putAll(super.getHeaders()); |
| | | // 由于修改了请求体的body,导致content-length长度不确定,因此需要删除原先的content-length |
| | | httpHeaders.remove(HttpHeaders.CONTENT_LENGTH); |
| | | httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); |
| | | return httpHeaders; |
| | | } |
| | | |
| | | }; |
| | | return serverHttpRequestDecorator; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public int getOrder() { |
| | | return HIGHEST_PRECEDENCE; |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.gateway.filter; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.core.constant.HttpStatus; |
| | |
| | | public class SignFilter implements GlobalFilter, Ordered { |
| | | private static final Logger log = LoggerFactory.getLogger(SignFilter.class); |
| | | |
| | | // 排除过滤的 uri 地址,nacos自行添加 |
| | | @Autowired |
| | | private IgnoreWhiteProperties ignoreWhite; |
| | | |
| | | @Autowired |
| | | private RedisService redisService; |
| | | |
| | | @Value("${security.sign}") |
| | | private boolean parameter_signature; |
| | | |
| | |
| | | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| | | ServerHttpRequest request = exchange.getRequest(); |
| | | ServerHttpRequest.Builder mutate = request.mutate(); |
| | | |
| | | |
| | | HttpMethod method = request.getMethod(); |
| | | if(method != HttpMethod.POST){ |
| | | return chain.filter(exchange.mutate().request(mutate.build()).build()); |
| | |
| | | log.error("[签名异常处理]请求路径:{}", exchange.getRequest().getPath()); |
| | | return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.BAD_REQUEST); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 校验签名 |
| | | * @return |
| | |
| | | .build()); |
| | | }); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 签名校验 |
| | | * @return |
| | |
| | | System.err.println("签名值:" + signUrlEncode); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 组装签名路径 |
| | | * @param params |
| | |
| | | // 构造签名键值对的格式 |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (String k : keySet) { |
| | | Object o = params.get(k); |
| | | if(o instanceof JSONObject || o instanceof JSONArray){ |
| | | continue; |
| | | } |
| | | String v = params.getString(k); |
| | | if(StringUtils.isNotEmpty(v)){ |
| | | sb.append(k + "=" + v + "&"); |
| | |
| | | import java.nio.CharBuffer; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.concurrent.atomic.AtomicReference; |
| | | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.cloud.gateway.filter.GatewayFilter; |
| | | import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; |
| | |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object> |
| | | { |
| | | private final static String[] VALIDATE_URL = new String[] { "/auth/login", "/auth/register" }; |
| | | |
| | | @Autowired |
| | | private ValidateCodeService validateCodeService; |
| | | |
| | | @Autowired |
| | | private CaptchaProperties captchaProperties; |
| | | |
| | | private static final String CODE = "code"; |
| | | |
| | | private static final String UUID = "uuid"; |
| | | |
| | | @Override |
| | | public GatewayFilter apply(Object config) |
| | | { |
| | | return (exchange, chain) -> { |
| | | ServerHttpRequest request = exchange.getRequest(); |
| | | |
| | | // 非登录/注册请求或验证码关闭,不处理 |
| | | if (!StringUtils.containsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) || !captchaProperties.getEnabled()) |
| | | { |
| | | return chain.filter(exchange); |
| | | } |
| | | |
| | | try |
| | | { |
| | | String rspStr = resolveBodyFromRequest(request); |
| | | JSONObject obj = JSON.parseObject(rspStr); |
| | | validateCodeService.checkCaptcha(obj.getString(CODE), obj.getString(UUID)); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | return ServletUtils.webFluxResponseWriter(exchange.getResponse(), e.getMessage()); |
| | | } |
| | | return chain.filter(exchange); |
| | | }; |
| | | } |
| | | |
| | | private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) |
| | | { |
| | | // 获取请求体 |
| | | Flux<DataBuffer> body = serverHttpRequest.getBody(); |
| | | AtomicReference<String> bodyRef = new AtomicReference<>(); |
| | | body.subscribe(buffer -> { |
| | | CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer()); |
| | | DataBufferUtils.release(buffer); |
| | | bodyRef.set(charBuffer.toString()); |
| | | }); |
| | | return bodyRef.get(); |
| | | } |
| | | public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object> { |
| | | private final static String[] VALIDATE_URL = new String[]{"/auth/login", "/auth/register"}; |
| | | private static final String CODE = "code"; |
| | | private static final String UUID = "uuid"; |
| | | @Autowired |
| | | private ValidateCodeService validateCodeService; |
| | | @Autowired |
| | | private CaptchaProperties captchaProperties; |
| | | |
| | | @Override |
| | | public GatewayFilter apply(Object config) { |
| | | return (exchange, chain) -> { |
| | | ServerHttpRequest request = exchange.getRequest(); |
| | | |
| | | // 非登录/注册请求或验证码关闭,不处理 |
| | | if (!StringUtils.containsAnyIgnoreCase(request.getURI().getPath(), VALIDATE_URL) || !captchaProperties.getEnabled()) { |
| | | return chain.filter(exchange); |
| | | } |
| | | |
| | | try { |
| | | String rspStr = resolveBodyFromRequest(request); |
| | | JSONObject obj = JSON.parseObject(rspStr); |
| | | validateCodeService.checkCaptcha(obj.getString(CODE), obj.getString(UUID)); |
| | | } catch (Exception e) { |
| | | return ServletUtils.webFluxResponseWriter(exchange.getResponse(), e.getMessage()); |
| | | } |
| | | return chain.filter(exchange); |
| | | }; |
| | | } |
| | | |
| | | private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) { |
| | | // 获取请求体 |
| | | Flux<DataBuffer> body = serverHttpRequest.getBody(); |
| | | AtomicReference<String> bodyRef = new AtomicReference<>(); |
| | | body.subscribe(buffer -> { |
| | | CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer()); |
| | | DataBufferUtils.release(buffer); |
| | | bodyRef.set(charBuffer.toString()); |
| | | }); |
| | | return bodyRef.get(); |
| | | } |
| | | } |
| | |
| | | */ |
| | | @Component |
| | | @ConditionalOnProperty(value = "security.xss.enabled", havingValue = "true") |
| | | public class XssFilter implements GlobalFilter, Ordered |
| | | { |
| | | private static final Logger log = LoggerFactory.getLogger(XssFilter.class); |
| | | // 跨站脚本的 xss 配置,nacos自行添加 |
| | | @Autowired |
| | | private XssProperties xss; |
| | | |
| | | @Override |
| | | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| | | ServerHttpRequest request = exchange.getRequest(); |
| | | // xss开关未开启 或 通过nacos关闭,不过滤 |
| | | if (!xss.getEnabled()) { |
| | | return chain.filter(exchange); |
| | | } |
| | | // GET DELETE 不过滤 |
| | | HttpMethod method = request.getMethod(); |
| | | if (method == null || method == HttpMethod.GET || method == HttpMethod.DELETE) { |
| | | return chain.filter(exchange); |
| | | } |
| | | // 非json类型,不过滤 |
| | | if (!isJsonRequest(exchange)) { |
| | | return chain.filter(exchange); |
| | | } |
| | | // excludeUrls 不过滤 |
| | | String url = request.getURI().getPath(); |
| | | if (StringUtils.matches(url, xss.getExcludeUrls())) { |
| | | return chain.filter(exchange); |
| | | } |
| | | ServerHttpRequestDecorator httpRequestDecorator = requestDecorator(exchange); |
| | | return chain.filter(exchange.mutate().request(httpRequestDecorator).build()); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | private ServerHttpRequestDecorator requestDecorator(ServerWebExchange exchange) { |
| | | ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) { |
| | | @Override |
| | | public Flux<DataBuffer> getBody() { |
| | | Flux<DataBuffer> body = super.getBody(); |
| | | return body.buffer().map(dataBuffers -> { |
| | | DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory(); |
| | | DataBuffer join = dataBufferFactory.join(dataBuffers); |
| | | byte[] content = new byte[join.readableByteCount()]; |
| | | join.read(content); |
| | | DataBufferUtils.release(join); |
| | | String bodyStr = new String(content, StandardCharsets.UTF_8); |
| | | // 防xss攻击过滤 |
| | | bodyStr = EscapeUtil.clean(bodyStr); |
| | | // 转成字节 |
| | | byte[] bytes = bodyStr.getBytes(); |
| | | NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT); |
| | | DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length); |
| | | buffer.write(bytes); |
| | | return buffer; |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | public HttpHeaders getHeaders() { |
| | | HttpHeaders httpHeaders = new HttpHeaders(); |
| | | httpHeaders.putAll(super.getHeaders()); |
| | | // 由于修改了请求体的body,导致content-length长度不确定,因此需要删除原先的content-length |
| | | httpHeaders.remove(HttpHeaders.CONTENT_LENGTH); |
| | | httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); |
| | | return httpHeaders; |
| | | } |
| | | |
| | | }; |
| | | return serverHttpRequestDecorator; |
| | | } |
| | | |
| | | /** |
| | | * 是否是Json请求 |
| | | * |
| | | * @param exchange HTTP请求 |
| | | */ |
| | | public boolean isJsonRequest(ServerWebExchange exchange) { |
| | | String header = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE); |
| | | return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); |
| | | } |
| | | |
| | | @Override |
| | | public int getOrder() |
| | | { |
| | | return -100; |
| | | } |
| | | public class XssFilter implements GlobalFilter, Ordered { |
| | | private static final Logger log = LoggerFactory.getLogger(XssFilter.class); |
| | | // 跨站脚本的 xss 配置,nacos自行添加 |
| | | @Autowired |
| | | private XssProperties xss; |
| | | |
| | | @Override |
| | | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { |
| | | ServerHttpRequest request = exchange.getRequest(); |
| | | // xss开关未开启 或 通过nacos关闭,不过滤 |
| | | if (!xss.getEnabled()) { |
| | | return chain.filter(exchange); |
| | | } |
| | | // GET DELETE 不过滤 |
| | | HttpMethod method = request.getMethod(); |
| | | if (method == null || method == HttpMethod.GET || method == HttpMethod.DELETE) { |
| | | return chain.filter(exchange); |
| | | } |
| | | // 非json类型,不过滤 |
| | | if (!isJsonRequest(exchange)) { |
| | | return chain.filter(exchange); |
| | | } |
| | | // excludeUrls 不过滤 |
| | | String url = request.getURI().getPath(); |
| | | if (StringUtils.matches(url, xss.getExcludeUrls())) { |
| | | return chain.filter(exchange); |
| | | } |
| | | ServerHttpRequestDecorator httpRequestDecorator = requestDecorator(exchange); |
| | | return chain.filter(exchange.mutate().request(httpRequestDecorator).build()); |
| | | } |
| | | |
| | | |
| | | private ServerHttpRequestDecorator requestDecorator(ServerWebExchange exchange) { |
| | | ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest()) { |
| | | @Override |
| | | public Flux<DataBuffer> getBody() { |
| | | Flux<DataBuffer> body = super.getBody(); |
| | | return body.buffer().map(dataBuffers -> { |
| | | DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory(); |
| | | DataBuffer join = dataBufferFactory.join(dataBuffers); |
| | | byte[] content = new byte[join.readableByteCount()]; |
| | | join.read(content); |
| | | DataBufferUtils.release(join); |
| | | String bodyStr = new String(content, StandardCharsets.UTF_8); |
| | | // 防xss攻击过滤 |
| | | bodyStr = EscapeUtil.clean(bodyStr); |
| | | // 转成字节 |
| | | byte[] bytes = bodyStr.getBytes(); |
| | | NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT); |
| | | DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length); |
| | | buffer.write(bytes); |
| | | return buffer; |
| | | }); |
| | | } |
| | | |
| | | @Override |
| | | public HttpHeaders getHeaders() { |
| | | HttpHeaders httpHeaders = new HttpHeaders(); |
| | | httpHeaders.putAll(super.getHeaders()); |
| | | // 由于修改了请求体的body,导致content-length长度不确定,因此需要删除原先的content-length |
| | | httpHeaders.remove(HttpHeaders.CONTENT_LENGTH); |
| | | httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); |
| | | return httpHeaders; |
| | | } |
| | | |
| | | }; |
| | | return serverHttpRequestDecorator; |
| | | } |
| | | |
| | | /** |
| | | * 是否是Json请求 |
| | | * |
| | | * @param exchange HTTP请求 |
| | | */ |
| | | public boolean isJsonRequest(ServerWebExchange exchange) { |
| | | String header = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE); |
| | | return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); |
| | | } |
| | | |
| | | @Override |
| | | public int getOrder() { |
| | | return -100; |
| | | } |
| | | } |
| | |
| | | */ |
| | | @Order(-1) |
| | | @Configuration |
| | | public class GatewayExceptionHandler implements ErrorWebExceptionHandler |
| | | { |
| | | private static final Logger log = LoggerFactory.getLogger(GatewayExceptionHandler.class); |
| | | |
| | | @Override |
| | | public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) |
| | | { |
| | | ServerHttpResponse response = exchange.getResponse(); |
| | | |
| | | if (exchange.getResponse().isCommitted()) |
| | | { |
| | | return Mono.error(ex); |
| | | } |
| | | |
| | | String msg; |
| | | |
| | | if (ex instanceof NotFoundException) |
| | | { |
| | | msg = "服务未找到"; |
| | | } |
| | | else if (ex instanceof ResponseStatusException) |
| | | { |
| | | ResponseStatusException responseStatusException = (ResponseStatusException) ex; |
| | | msg = responseStatusException.getMessage(); |
| | | } |
| | | else |
| | | { |
| | | msg = "内部服务器错误"; |
| | | } |
| | | |
| | | log.error("[网关异常处理]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), ex.getMessage()); |
| | | |
| | | return ServletUtils.webFluxResponseWriter(response, msg); |
| | | } |
| | | public class GatewayExceptionHandler implements ErrorWebExceptionHandler { |
| | | private static final Logger log = LoggerFactory.getLogger(GatewayExceptionHandler.class); |
| | | |
| | | @Override |
| | | public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) { |
| | | ServerHttpResponse response = exchange.getResponse(); |
| | | |
| | | if (exchange.getResponse().isCommitted()) { |
| | | return Mono.error(ex); |
| | | } |
| | | |
| | | String msg; |
| | | |
| | | if (ex instanceof NotFoundException) { |
| | | msg = "服务未找到"; |
| | | } else if (ex instanceof ResponseStatusException) { |
| | | ResponseStatusException responseStatusException = (ResponseStatusException) ex; |
| | | msg = responseStatusException.getMessage(); |
| | | } else { |
| | | msg = "内部服务器错误"; |
| | | } |
| | | |
| | | log.error("[网关异常处理]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), ex.getMessage()); |
| | | |
| | | return ServletUtils.webFluxResponseWriter(response, msg); |
| | | } |
| | | } |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class SentinelFallbackHandler implements WebExceptionHandler |
| | | { |
| | | private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) |
| | | { |
| | | return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求超过最大数,请稍候再试"); |
| | | } |
| | | |
| | | @Override |
| | | public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) |
| | | { |
| | | if (exchange.getResponse().isCommitted()) |
| | | { |
| | | return Mono.error(ex); |
| | | } |
| | | if (!BlockException.isBlockException(ex)) |
| | | { |
| | | return Mono.error(ex); |
| | | } |
| | | return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange)); |
| | | } |
| | | |
| | | private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable) |
| | | { |
| | | return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable); |
| | | } |
| | | public class SentinelFallbackHandler implements WebExceptionHandler { |
| | | private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) { |
| | | return ServletUtils.webFluxResponseWriter(exchange.getResponse(), "请求超过最大数,请稍候再试"); |
| | | } |
| | | |
| | | @Override |
| | | public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) { |
| | | if (exchange.getResponse().isCommitted()) { |
| | | return Mono.error(ex); |
| | | } |
| | | if (!BlockException.isBlockException(ex)) { |
| | | return Mono.error(ex); |
| | | } |
| | | return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange)); |
| | | } |
| | | |
| | | private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable) { |
| | | return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable); |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.gateway.handler; |
| | | |
| | | import java.util.Optional; |
| | | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | |
| | | |
| | | @RestController |
| | | @RequestMapping("/swagger-resources") |
| | | public class SwaggerHandler |
| | | { |
| | | @Autowired(required = false) |
| | | private SecurityConfiguration securityConfiguration; |
| | | |
| | | @Autowired(required = false) |
| | | private UiConfiguration uiConfiguration; |
| | | |
| | | private final SwaggerResourcesProvider swaggerResources; |
| | | |
| | | @Autowired |
| | | public SwaggerHandler(SwaggerResourcesProvider swaggerResources) |
| | | { |
| | | this.swaggerResources = swaggerResources; |
| | | } |
| | | |
| | | @GetMapping("/configuration/security") |
| | | public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() |
| | | { |
| | | return Mono.just(new ResponseEntity<>( |
| | | Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), |
| | | HttpStatus.OK)); |
| | | } |
| | | |
| | | @GetMapping("/configuration/ui") |
| | | public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() |
| | | { |
| | | return Mono.just(new ResponseEntity<>( |
| | | Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); |
| | | } |
| | | |
| | | @SuppressWarnings("rawtypes") |
| | | @GetMapping("") |
| | | public Mono<ResponseEntity> swaggerResources() |
| | | { |
| | | return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); |
| | | } |
| | | public class SwaggerHandler { |
| | | private final SwaggerResourcesProvider swaggerResources; |
| | | @Autowired(required = false) |
| | | private SecurityConfiguration securityConfiguration; |
| | | @Autowired(required = false) |
| | | private UiConfiguration uiConfiguration; |
| | | |
| | | @Autowired |
| | | public SwaggerHandler(SwaggerResourcesProvider swaggerResources) { |
| | | this.swaggerResources = swaggerResources; |
| | | } |
| | | |
| | | @GetMapping("/configuration/security") |
| | | public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() { |
| | | return Mono.just(new ResponseEntity<>( |
| | | Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), |
| | | HttpStatus.OK)); |
| | | } |
| | | |
| | | @GetMapping("/configuration/ui") |
| | | public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() { |
| | | return Mono.just(new ResponseEntity<>( |
| | | Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); |
| | | } |
| | | |
| | | @SuppressWarnings("rawtypes") |
| | | @GetMapping("") |
| | | public Mono<ResponseEntity> swaggerResources() { |
| | | return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.gateway.handler; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class ValidateCodeHandler implements HandlerFunction<ServerResponse> |
| | | { |
| | | @Autowired |
| | | private ValidateCodeService validateCodeService; |
| | | |
| | | @Override |
| | | public Mono<ServerResponse> handle(ServerRequest serverRequest) |
| | | { |
| | | AjaxResult ajax; |
| | | try |
| | | { |
| | | ajax = validateCodeService.createCaptcha(); |
| | | } |
| | | catch (CaptchaException | IOException e) |
| | | { |
| | | return Mono.error(e); |
| | | } |
| | | return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax)); |
| | | } |
| | | public class ValidateCodeHandler implements HandlerFunction<ServerResponse> { |
| | | @Autowired |
| | | private ValidateCodeService validateCodeService; |
| | | |
| | | @Override |
| | | public Mono<ServerResponse> handle(ServerRequest serverRequest) { |
| | | AjaxResult ajax; |
| | | try { |
| | | ajax = validateCodeService.createCaptcha(); |
| | | } catch (CaptchaException | IOException e) { |
| | | return Mono.error(e); |
| | | } |
| | | return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(ajax)); |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.gateway.service; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import com.ruoyi.common.core.exception.CaptchaException; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public interface ValidateCodeService |
| | | { |
| | | /** |
| | | * 生成验证码 |
| | | */ |
| | | public AjaxResult createCaptcha() throws IOException, CaptchaException; |
| | | |
| | | /** |
| | | * 校验验证码 |
| | | */ |
| | | public void checkCaptcha(String key, String value) throws CaptchaException; |
| | | public interface ValidateCodeService { |
| | | /** |
| | | * 生成验证码 |
| | | */ |
| | | public AjaxResult createCaptcha() throws IOException, CaptchaException; |
| | | |
| | | /** |
| | | * 校验验证码 |
| | | */ |
| | | public void checkCaptcha(String key, String value) throws CaptchaException; |
| | | } |
| | |
| | | import java.util.concurrent.TimeUnit; |
| | | import javax.annotation.Resource; |
| | | import javax.imageio.ImageIO; |
| | | |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.FastByteArrayOutputStream; |
| | |
| | | * @author ruoyi |
| | | */ |
| | | @Service |
| | | public class ValidateCodeServiceImpl implements ValidateCodeService |
| | | { |
| | | @Resource(name = "captchaProducer") |
| | | private Producer captchaProducer; |
| | | |
| | | @Resource(name = "captchaProducerMath") |
| | | private Producer captchaProducerMath; |
| | | |
| | | @Autowired |
| | | private RedisService redisService; |
| | | |
| | | @Autowired |
| | | private CaptchaProperties captchaProperties; |
| | | |
| | | /** |
| | | * 生成验证码 |
| | | */ |
| | | @Override |
| | | public AjaxResult createCaptcha() throws IOException, CaptchaException |
| | | { |
| | | AjaxResult ajax = AjaxResult.success(); |
| | | boolean captchaEnabled = captchaProperties.getEnabled(); |
| | | ajax.put("captchaEnabled", captchaEnabled); |
| | | if (!captchaEnabled) |
| | | { |
| | | return ajax; |
| | | } |
| | | |
| | | // 保存验证码信息 |
| | | String uuid = IdUtils.simpleUUID(); |
| | | String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; |
| | | |
| | | String capStr = null, code = null; |
| | | BufferedImage image = null; |
| | | |
| | | String captchaType = captchaProperties.getType(); |
| | | // 生成验证码 |
| | | if ("math".equals(captchaType)) |
| | | { |
| | | String capText = captchaProducerMath.createText(); |
| | | capStr = capText.substring(0, capText.lastIndexOf("@")); |
| | | code = capText.substring(capText.lastIndexOf("@") + 1); |
| | | image = captchaProducerMath.createImage(capStr); |
| | | } |
| | | else if ("char".equals(captchaType)) |
| | | { |
| | | capStr = code = captchaProducer.createText(); |
| | | image = captchaProducer.createImage(capStr); |
| | | } |
| | | |
| | | redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); |
| | | // 转换流信息写出 |
| | | FastByteArrayOutputStream os = new FastByteArrayOutputStream(); |
| | | try |
| | | { |
| | | ImageIO.write(image, "jpg", os); |
| | | } |
| | | catch (IOException e) |
| | | { |
| | | return AjaxResult.error(e.getMessage()); |
| | | } |
| | | |
| | | ajax.put("uuid", uuid); |
| | | ajax.put("img", Base64.encode(os.toByteArray())); |
| | | return ajax; |
| | | } |
| | | |
| | | /** |
| | | * 校验验证码 |
| | | */ |
| | | @Override |
| | | public void checkCaptcha(String code, String uuid) throws CaptchaException |
| | | { |
| | | if (StringUtils.isEmpty(code)) |
| | | { |
| | | throw new CaptchaException("验证码不能为空"); |
| | | } |
| | | if (StringUtils.isEmpty(uuid)) |
| | | { |
| | | throw new CaptchaException("验证码已失效"); |
| | | } |
| | | String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; |
| | | String captcha = redisService.getCacheObject(verifyKey); |
| | | redisService.deleteObject(verifyKey); |
| | | |
| | | if (!code.equalsIgnoreCase(captcha)) |
| | | { |
| | | throw new CaptchaException("验证码错误"); |
| | | } |
| | | } |
| | | public class ValidateCodeServiceImpl implements ValidateCodeService { |
| | | @Resource(name = "captchaProducer") |
| | | private Producer captchaProducer; |
| | | |
| | | @Resource(name = "captchaProducerMath") |
| | | private Producer captchaProducerMath; |
| | | |
| | | @Autowired |
| | | private RedisService redisService; |
| | | |
| | | @Autowired |
| | | private CaptchaProperties captchaProperties; |
| | | |
| | | /** |
| | | * 生成验证码 |
| | | */ |
| | | @Override |
| | | public AjaxResult createCaptcha() throws IOException, CaptchaException { |
| | | AjaxResult ajax = AjaxResult.success(); |
| | | boolean captchaEnabled = captchaProperties.getEnabled(); |
| | | ajax.put("captchaEnabled", captchaEnabled); |
| | | if (!captchaEnabled) { |
| | | return ajax; |
| | | } |
| | | |
| | | // 保存验证码信息 |
| | | String uuid = IdUtils.simpleUUID(); |
| | | String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; |
| | | |
| | | String capStr = null, code = null; |
| | | BufferedImage image = null; |
| | | |
| | | String captchaType = captchaProperties.getType(); |
| | | // 生成验证码 |
| | | if ("math".equals(captchaType)) { |
| | | String capText = captchaProducerMath.createText(); |
| | | capStr = capText.substring(0, capText.lastIndexOf("@")); |
| | | code = capText.substring(capText.lastIndexOf("@") + 1); |
| | | image = captchaProducerMath.createImage(capStr); |
| | | } else if ("char".equals(captchaType)) { |
| | | capStr = code = captchaProducer.createText(); |
| | | image = captchaProducer.createImage(capStr); |
| | | } |
| | | |
| | | redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); |
| | | // 转换流信息写出 |
| | | FastByteArrayOutputStream os = new FastByteArrayOutputStream(); |
| | | try { |
| | | ImageIO.write(image, "jpg", os); |
| | | } catch (IOException e) { |
| | | return AjaxResult.error(e.getMessage()); |
| | | } |
| | | |
| | | ajax.put("uuid", uuid); |
| | | ajax.put("img", Base64.encode(os.toByteArray())); |
| | | return ajax; |
| | | } |
| | | |
| | | /** |
| | | * 校验验证码 |
| | | */ |
| | | @Override |
| | | public void checkCaptcha(String code, String uuid) throws CaptchaException { |
| | | if (StringUtils.isEmpty(code)) { |
| | | throw new CaptchaException("验证码不能为空"); |
| | | } |
| | | if (StringUtils.isEmpty(uuid)) { |
| | | throw new CaptchaException("验证码已失效"); |
| | | } |
| | | String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; |
| | | String captcha = redisService.getCacheObject(verifyKey); |
| | | redisService.deleteObject(verifyKey); |
| | | |
| | | if (!code.equalsIgnoreCase(captcha)) { |
| | | throw new CaptchaException("验证码错误"); |
| | | } |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.account.controller; |
| | | |
| | | |
| | | import cn.hutool.core.date.DateTime; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; |
| | |
| | | import com.ruoyi.account.api.model.*; |
| | | import com.ruoyi.account.api.vo.CouponListVOVO; |
| | | import com.ruoyi.account.service.*; |
| | | import com.ruoyi.account.util.PointDetailUtil; |
| | | import com.ruoyi.account.util.SignDayUtil; |
| | | import com.ruoyi.account.wx.body.resp.Code2SessionRespBody; |
| | | import com.ruoyi.account.wx.body.resq.Code2SessionResqBody; |
| | | import com.ruoyi.account.wx.model.WeixinProperties; |
| | |
| | | import com.ruoyi.account.util.GiveVipUtil; |
| | | import com.ruoyi.common.core.constant.Constants; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.enums.status.AppUserStatusEnum; |
| | | import com.ruoyi.common.core.utils.JwtUtils; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.bean.BeanUtils; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import com.ruoyi.common.redis.service.RedisService; |
| | | import com.ruoyi.common.security.annotation.RequiresPermissions; |
| | | import com.ruoyi.common.security.auth.AuthUtil; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import com.ruoyi.common.security.utils.SecurityUtils; |
| | | import com.ruoyi.order.api.feignClient.ChargingOrderClient; |
| | | import com.ruoyi.order.api.feignClient.ExchangeOrderClient; |
| | | import com.ruoyi.order.api.model.TChargingOrder; |
| | | import com.ruoyi.order.api.model.TExchangeOrder; |
| | | import com.ruoyi.other.api.domain.TCompany; |
| | | import com.ruoyi.other.api.domain.TCoupon; |
| | | import com.ruoyi.other.api.domain.TIntegralRule; |
| | | import com.ruoyi.other.api.domain.TUserTag; |
| | | import com.ruoyi.other.api.feignClient.IntegralRuleClient; |
| | | import com.ruoyi.other.api.feignClient.OtherClient; |
| | | import com.ruoyi.system.api.domain.SysRole; |
| | | import com.ruoyi.system.api.model.LoginUser; |
| | | import com.ruoyi.system.api.model.LoginUserApplet; |
| | | import io.swagger.annotations.ApiImplicitParam; |
| | | import io.swagger.annotations.ApiImplicitParams; |
| | |
| | | import org.springframework.web.client.RestTemplate; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.time.Duration; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | |
| | | |
| | | @Resource |
| | | private TAppUserIntegralChangeService integralChangeService; |
| | | @Resource |
| | | private SignDayUtil signDayUtil; |
| | | |
| | | @Resource |
| | | private ExchangeOrderClient exchangeOrderClient; |
| | |
| | | private TokenService tokenService; |
| | | @Autowired |
| | | private RedisService redisService; |
| | | @Autowired |
| | | private WeixinProperties wxConfig; |
| | | @Autowired |
| | | private RestTemplate wxRestTemplate; |
| | | @Resource |
| | | private PointDetailUtil pointDetailUtil; |
| | | |
| | | @Resource |
| | | private TAppUserSignService signService; |
| | |
| | | private TAppCouponService appCouponService; |
| | | @Resource |
| | | private TAppUserCarService carService; |
| | | @Resource |
| | | private IntegralRuleClient integralRuleClient; |
| | | |
| | | |
| | | |
| | | |
| | | @ApiOperation(value = "查询当前用户是否为会员 0否1是", tags = {"小程序--查询当前用户是否为会员"}) |
| | |
| | | |
| | | |
| | | @ApiOperation(value = "单位下拉框", tags = {"用户管理-单位管理"}) |
| | | @PostMapping(value = "/unit/select") |
| | | @GetMapping(value = "/unit/select") |
| | | public R<List<TCompany>> unitSelect() { |
| | | UnitListQueryDto unitListQueryDto = new UnitListQueryDto(); |
| | | unitListQueryDto.setPageCurr(1); |
| | |
| | | } |
| | | List<Integer> vipIds = new ArrayList<>(); |
| | | vipIds = page.getRecords().stream().map(TAppUser::getVipId).collect(Collectors.toList()); |
| | | //获取会员map |
| | | R<Map<Integer, String>> vipMap = otherClient.getVipMap(vipIds); |
| | | //循环处理 |
| | | for (TAppUser appUser : page.getRecords()) { |
| | | //拿到最新的tagId |
| | | TAppUserTag one = appUserTagService.lambdaQuery().eq(TAppUserTag::getAppUserId, appUser.getId()).orderByDesc(TAppUserTag::getCreateTime).last("limit 1").one(); |
| | | if (one!=null) { |
| | | //设置最新的tagName |
| | | R<TUserTag> byIdTag = otherClient.getByIdTag(one.getUserTagId()); |
| | | if (byIdTag.getData() != null) { |
| | | appUser.setTagName(byIdTag.getData().getName()); |
| | | } |
| | | } |
| | | //匹配vipMap的值 |
| | | appUser.setVipName(vipMap.getData().get(appUser.getVipId())); |
| | | //累计充电次数 |
| | | R<Long> useOrderCount = chargingOrderClient.useOrderCount(appUser.getId()); |
| | | appUser.setOrderCount(useOrderCount.getData()); |
| | | appUser.setUid(appUser.getId().toString()); |
| | | |
| | | } |
| | | return R.ok(page); |
| | | } |
| | | |
| | | @ApiOperation(value = "会员列表", tags = {"用户管理-会员列表"}) |
| | | @PostMapping(value = "/user/vip/page") |
| | | public R<Page<TAppUser>> vipPage(@RequestBody UserListQueryDto userListQueryDto) { |
| | | List<Long> userIds = new ArrayList<>(); |
| | | //如果要筛选标签。用标签获取useids |
| | | if (userListQueryDto.getUserTagId() != null){ |
| | | userIds = appUserTagService.lambdaQuery().eq(TAppUserTag::getUserTagId, userListQueryDto.getUserTagId()).list().stream().map(TAppUserTag::getAppUserId).collect(Collectors.toList()); |
| | | } |
| | | //列表查询 |
| | | Page<TAppUser> page = appUserService.lambdaQuery() |
| | | .like(userListQueryDto.getUserPhone() != null && !"".equals(userListQueryDto.getUserPhone()), TAppUser::getPhone, userListQueryDto.getUserPhone()) |
| | | .eq(userListQueryDto.getCompanyId() != null, TAppUser::getCompanyId, userListQueryDto.getCompanyId()) |
| | | .eq(userListQueryDto.getCityCode() != null && !"".equals(userListQueryDto.getCityCode()), TAppUser::getCityCode, userListQueryDto.getCityCode()) |
| | | .eq(userListQueryDto.getStatus() != null, TAppUser::getStatus, userListQueryDto.getStatus()) |
| | | .eq(userListQueryDto.getVipTypeId() != null, TAppUser::getVipId, userListQueryDto.getVipTypeId()) |
| | | .in(!userIds.isEmpty(),TAppUser::getId,userIds) |
| | | .page(Page.of(userListQueryDto.getPageCurr(), userListQueryDto.getPageSize())); |
| | | if (page.getRecords().isEmpty()){ |
| | | return R.ok(page); |
| | | } |
| | | List<Integer> vipIds = new ArrayList<>(); |
| | | vipIds = page.getRecords().stream().map(TAppUser::getVipId).collect(Collectors.toList()); |
| | | //获取会员map |
| | | R<Map<Integer, String>> vipMap = otherClient.getVipMap(vipIds); |
| | | //循环处理 |
| | |
| | | } |
| | | |
| | | @ApiOperation(value = "用户详情", tags = {"用户管理-用户列表"}) |
| | | @PostMapping(value = "/user/detail/{id}") |
| | | @GetMapping(value = "/user/detail/{id}") |
| | | public R<UserDetailDto> userDetail(@PathVariable Long id) { |
| | | TAppUser user = appUserService.getById(id); |
| | | UserDetailDto userDetailDto = new UserDetailDto(); |
| | |
| | | |
| | | List<Integer> tagIds = appUserTagService.lambdaQuery().eq(TAppUserTag::getAppUserId, id).orderByDesc(TAppUserTag::getCreateTime).list().stream().map(TAppUserTag::getUserTagId).collect(Collectors.toList()); |
| | | R<Map<Integer, String>> tagMap = otherClient.getTagMap(tagIds); |
| | | userDetailDto.setTagName(tagMap.getData().values().toString()); |
| | | userDetailDto.setTagName(tagMap.getData().values() |
| | | .stream() |
| | | .collect(Collectors.joining(","))); |
| | | return R.ok(userDetailDto); |
| | | } |
| | | |
| | |
| | | appUser.setStatus(userChangeDto.getStatus()); |
| | | appUserService.updateById(appUser); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @ApiOperation(value = "修改单位", tags = {"后台-用户管理-用户列表"}) |
| | | @PostMapping(value = "/user/unit/change") |
| | | public R unitChange(@RequestBody UnitChangeDto unitChangeDto) { |
| | | for (String s : unitChangeDto.getIds().split(",")) { |
| | | TAppUser byId = appUserService.getById(s); |
| | | byId.setCompanyId(unitChangeDto.getUnitId()); |
| | | appUserService.updateById(byId); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | | @ApiOperation(value = "删除用户", tags = {"后台-用户管理-用户列表"}) |
| | | @DeleteMapping(value = "/user/delete") |
| | | public R userDelete(String ids) { |
| | | String[] split = ids.split(","); |
| | | for (String s : split) { |
| | | appUserService.removeById(s); |
| | | } |
| | | return R.ok(); |
| | | |
| | | } |
| | | |
| | | @ApiOperation(value = "个人中心信息", tags = {"小程序-个人中心"}) |
| | |
| | | @ApiOperation(value = "赠送会员", tags = {"用户管理-用户列表"}) |
| | | @PostMapping(value = "/user/give/vip") |
| | | public R giveVip(@RequestBody GiveVipDto giveVipDto) { |
| | | TAppUser nowUser = appUserService.getById(giveVipDto.getUserId()); |
| | | String[] split = giveVipDto.getUserIds().split(","); |
| | | for (String s : split) { |
| | | |
| | | |
| | | TAppUser nowUser = appUserService.getById(s); |
| | | |
| | | int plusDay = 0; |
| | | if (giveVipDto.getType() == 1) { |
| | |
| | | |
| | | appUserService.updateById(nowUser); |
| | | //执行一次赠送优惠卷的定时任务 |
| | | |
| | | } |
| | | return R.ok(); |
| | | } |
| | | |
| | |
| | | TAppUser appUser = appUserService.getById(userId); |
| | | appUser.setPhone(dto.getPhone()); |
| | | appUserService.updateById(appUser); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation(value = "注销接口", tags = {"小程序-用户管理-注销账号"}) |
| | | @DeleteMapping("/logoff") |
| | | public AjaxResult<?> logoff(HttpServletRequest request) { |
| | | String token = SecurityUtils.getToken(request); |
| | | if (StringUtils.isNotEmpty(token)) |
| | | { |
| | | String userId = JwtUtils.getUserId(token); |
| | | // 账号注销 |
| | | appUserService.update(Wrappers.<TAppUser>lambdaUpdate().set(TAppUser::getStatus, AppUserStatusEnum.LOGOFF.getCode()).eq(TAppUser::getId, userId)); |
| | | // 删除用户缓存记录 |
| | | AuthUtil.logoutByToken(token); |
| | | } |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | |
| | | .last("LIMIT 1"))); |
| | | } |
| | | |
| | | // @ApiOperation(value = "签到", tags = {"小程序-个人中心-签到"}) |
| | | // @PostMapping(value = "/user/sign") |
| | | // public R sign() { |
| | | // |
| | | // } |
| | | @ApiOperation(value = "签到", tags = {"小程序-个人中心-签到"}) |
| | | @PostMapping(value = "/user/sign") |
| | | public R sign() { |
| | | LoginUserApplet loginUserApplet = tokenService.getLoginUserApplet(); |
| | | Long userId = loginUserApplet.getUserId(); |
| | | |
| | | TAppUser byId = appUserService.getById(userId); |
| | | |
| | | |
| | | if (signService.lambdaQuery().eq(TAppUserSign::getSignDay, LocalDate.now()).eq(TAppUserSign::getAppUserId, userId).count()>0){ |
| | | return R.fail("今日已签到"); |
| | | } |
| | | //签到业务 |
| | | TAppUserSign appUserSign = new TAppUserSign(); |
| | | appUserSign.setSignDay(LocalDate.now()); |
| | | appUserSign.setRewardPoints(2); |
| | | appUserSign.setCreateTime(LocalDateTime.now()); |
| | | appUserSign.setAppUserId(userId); |
| | | signService.save(appUserSign); |
| | | //签到加积分记录 |
| | | R<TIntegralRule> set = integralRuleClient.getSet(); |
| | | TIntegralRule data = set.getData(); |
| | | JSONObject jsonObject = JSON.parseObject(data.getAddVehiclesEarnsPoints()); |
| | | //增加每日积分 |
| | | Integer points = 0; |
| | | Integer point = jsonObject.getInteger("num1"); |
| | | points= points+point; |
| | | JSONArray num2 = jsonObject.getJSONArray("num2"); |
| | | if (num2!=null) { |
| | | //获取连续签到的规则放入map |
| | | Map<Integer,Integer> map = new HashMap<>(); |
| | | for (Object o : num2) { |
| | | String o1 = (String) o; |
| | | String[] split = o1.split(","); |
| | | map.put(Integer.parseInt(split[0]), Integer.parseInt(split[1])); |
| | | } |
| | | //加上今日签到,计算连续了多少天,如果到达就增加奖励的分数 |
| | | int days = signDayUtil.calculateContinuousSignDays(userId); |
| | | Integer i = map.get(days); |
| | | if (i!=null){ |
| | | points= points+i; |
| | | appUserSign.setIsGift(1); |
| | | signService.updateById(appUserSign); |
| | | } |
| | | } |
| | | pointDetailUtil.addDetail(byId.getPoints(),byId.getPoints()+points,1,userId,"每日签到",""); |
| | | byId.setPoints(byId.getPoints()+points); |
| | | appUserService.updateById(byId); |
| | | return R.ok(); |
| | | } |
| | | |
| | | |
| | | @ApiOperation(value = "添加编辑车辆", tags = {"小程序-个人中心-车辆"}) |
| | | @PostMapping(value = "/user/car/addOrUpdate") |
| | | public R carAdd(@RequestBody TAppUserCar appUserCar) { |
| | | |
| | | LoginUserApplet loginUserApplet = tokenService.getLoginUserApplet(); |
| | | Long userId = loginUserApplet.getUserId(); |
| | | TAppUser byId = appUserService.getById(userId); |
| | | |
| | | |
| | | //如果是第一次添加车辆,增加积分 |
| | | Long count = appUserCarService.lambdaQuery().eq(TAppUserCar::getAppUserId, userId).count(); |
| | | |
| | | |
| | | if (count==0){ |
| | | R<TIntegralRule> set = integralRuleClient.getSet(); |
| | | TIntegralRule data = set.getData(); |
| | | JSONObject jsonObject = JSON.parseObject(data.getAddVehiclesEarnsPoints()); |
| | | |
| | | |
| | | Integer point = 0; |
| | | //增加车牌50分,必填 |
| | | point = point+jsonObject.getInteger("num1"); |
| | | //增加车型分 |
| | | if (StringUtils.isNotEmpty(appUserCar.getVehicleModel())){ |
| | | point = point+jsonObject.getInteger("num2"); |
| | | } |
| | | //增加车辆用途分 |
| | | if (StringUtils.isNotEmpty(appUserCar.getVehicleUse())){ |
| | | point = point+jsonObject.getInteger("num3"); |
| | | } |
| | | //增加续航分 |
| | | if (StringUtils.isNotEmpty(appUserCar.getEndurance())){ |
| | | point = point+jsonObject.getInteger("num4"); |
| | | } |
| | | |
| | | //增加积分记录 |
| | | pointDetailUtil.addDetail(byId.getPoints(),byId.getPoints()+point,5,userId,appUserCar.getLicensePlate(),""); |
| | | byId.setPoints(byId.getPoints()+point); |
| | | appUserService.updateById(byId); |
| | | |
| | | |
| | | } |
| | | |
| | | // |
| | | appUserCarService.saveOrUpdate(appUserCar); |
| | | |
| | | return R.ok(); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | @ApiOperation(value = "标签删除", tags = {"用户管理-用户标签管理"}) |
| | | @DeleteMapping(value = "/tags/delete") |
| | | public R delete(@PathVariable String ids) { |
| | | public R delete(String ids) { |
| | | //拿到单位列表 |
| | | String[] split = ids.split(","); |
| | | for (String id : split) { |
| | |
| | | package com.ruoyi.account.controller; |
| | | |
| | | |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.ruoyi.account.api.model.TInvoiceInformation; |
| | | import com.ruoyi.account.service.TInvoiceInformationService; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @RequestMapping("/t-invoice-information") |
| | | public class TInvoiceInformationController { |
| | | |
| | | @Resource |
| | | private TInvoiceInformationService invoiceInformationService; |
| | | |
| | | @Resource |
| | | private TokenService tokenService; |
| | | |
| | | |
| | | @ResponseBody |
| | | @GetMapping(value = "/getInvoiceInformationList") |
| | | @ApiOperation(value = "获取开票抬头数据列表", tags = {"小程序-充电发票"}) |
| | | public AjaxResult<List<TInvoiceInformation>> getInvoiceInformationList(){ |
| | | Long userId = tokenService.getLoginUserApplet().getUserId(); |
| | | List<TInvoiceInformation> list = invoiceInformationService.list(new LambdaQueryWrapper<TInvoiceInformation>().eq(TInvoiceInformation::getAppUserId, userId).eq(TInvoiceInformation::getDelFlag, 0)); |
| | | return AjaxResult.success(list); |
| | | } |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping(value = "/addInvoiceInformation") |
| | | @ApiOperation(value = "添加开票抬头数据", tags = {"小程序-充电发票"}) |
| | | public AjaxResult addInvoiceInformation(@RequestBody TInvoiceInformation invoiceInformation){ |
| | | Long userId = tokenService.getLoginUserApplet().getUserId(); |
| | | //如果当前是默认抬头,则需要去除其他的默认配置 |
| | | if(1 == invoiceInformation.getIsDefault()){ |
| | | TInvoiceInformation one = invoiceInformationService.getOne(new LambdaQueryWrapper<TInvoiceInformation>().eq(TInvoiceInformation::getDelFlag, 0) |
| | | .eq(TInvoiceInformation::getIsDefault, 1).eq(TInvoiceInformation::getAppUserId, userId)); |
| | | if(null != one){ |
| | | one.setIsDefault(0); |
| | | invoiceInformationService.updateById(one); |
| | | } |
| | | } |
| | | |
| | | invoiceInformation.setAppUserId(userId); |
| | | invoiceInformationService.save(invoiceInformation); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | @ResponseBody |
| | | @GetMapping(value = "/getInvoiceInformationInfo/{id}") |
| | | @ApiOperation(value = "获取开票抬头详情数据", tags = {"小程序-充电发票"}) |
| | | public AjaxResult<TInvoiceInformation> getInvoiceInformationInfo(@PathVariable String id){ |
| | | TInvoiceInformation information = invoiceInformationService.getById(id); |
| | | return AjaxResult.success(information); |
| | | } |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping(value = "/editInvoiceInformation") |
| | | @ApiOperation(value = "编辑开票抬头数据", tags = {"小程序-充电发票"}) |
| | | public AjaxResult editInvoiceInformation(@RequestBody TInvoiceInformation invoiceInformation){ |
| | | Long userId = tokenService.getLoginUserApplet().getUserId(); |
| | | //如果当前是默认抬头,则需要去除其他的默认配置 |
| | | if(1 == invoiceInformation.getIsDefault()){ |
| | | TInvoiceInformation one = invoiceInformationService.getOne(new LambdaQueryWrapper<TInvoiceInformation>().eq(TInvoiceInformation::getDelFlag, 0) |
| | | .eq(TInvoiceInformation::getIsDefault, 1).eq(TInvoiceInformation::getAppUserId, userId)); |
| | | if(null != one && !one.getId().equals(invoiceInformation.getId())){ |
| | | one.setIsDefault(0); |
| | | invoiceInformationService.updateById(one); |
| | | } |
| | | } |
| | | invoiceInformationService.updateById(invoiceInformation); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | * @return |
| | | */ |
| | | Map<String, Object> getUserInfo(TAppUser appUser); |
| | | |
| | | /** |
| | | * 账号判断 |
| | | * @param status |
| | | */ |
| | | public void throwInfo(Integer status); |
| | | } |
| | |
| | | import com.ruoyi.account.service.TAppUserService; |
| | | import com.ruoyi.account.wx.model.WeixinProperties; |
| | | import com.ruoyi.account.wx.pojo.AppletUserDecodeData; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import com.ruoyi.system.api.model.LoginUserApplet; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | appUser.setPhone(appletUserDecodeData.getPhoneNumber()); |
| | | } |
| | | } |
| | | if(Objects.nonNull(appUser.getStatus())){ |
| | | throwInfo(appUser.getStatus()); |
| | | } |
| | | appUser.setAvatar(appletUserDecodeData.getAvatarUrl()); |
| | | appUser.setCity(appletUserDecodeData.getCity()); |
| | | appUser.setName(appletUserDecodeData.getNickName()); |
| | |
| | | appUser.setPhone(userInfo.getMobile()); |
| | | } |
| | | } |
| | | if(Objects.nonNull(appUser.getStatus())){ |
| | | throwInfo(appUser.getStatus()); |
| | | } |
| | | appUser.setAvatar(userInfo.getAvatar()); |
| | | appUser.setCity(userInfo.getCity()); |
| | | appUser.setName(userInfo.getNickName()); |
| | |
| | | tokenInfos.put("info",loginUserApplet); |
| | | return tokenInfos; |
| | | } |
| | | |
| | | @Override |
| | | public void throwInfo(Integer status){ |
| | | switch (status){ |
| | | case 2: |
| | | throw new ServiceException("账号被冻结,请联系管理员"); |
| | | case 3: |
| | | throw new ServiceException("账号已注销,请重新注册使用"); |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | } |
| | |
| | | tAppUserVipDetail.setEndTime(LocalDateTime.now().plusMonths(plusDay).minusDays(1)); |
| | | tAppUserVipDetail.setVipId(vipId); |
| | | |
| | | R<TVip> info = vipClient.getInfo(vipId); |
| | | R<TVip> info = vipClient.getInfo1(vipId); |
| | | TVip vip = info.getData(); |
| | | List<SendCouponDto> javaList = JSON.parseArray(vip.getCoupon()).toJavaList(SendCouponDto.class); |
| | | |
New file |
| | |
| | | package com.ruoyi.account.util; |
| | | |
| | | import cn.hutool.core.date.DateTime; |
| | | import cn.hutool.core.date.DateUtil; |
| | | import com.ruoyi.account.api.model.TAppUserSign; |
| | | import com.ruoyi.account.service.TAppUserSignService; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.time.LocalDate; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | @Component |
| | | public class SignDayUtil { |
| | | |
| | | // 假设这是你的 signService 接口或者实现类 |
| | | @Resource |
| | | private TAppUserSignService signService; |
| | | |
| | | /** |
| | | * 计算用户的最近连续签到天数 |
| | | * @param userId 用户ID |
| | | * @return 连续签到的最大天数 |
| | | */ |
| | | public int calculateContinuousSignDays(Long userId) { |
| | | DateTime startOfMonth = DateUtil.beginOfMonth(new Date()); |
| | | DateTime endOfMonth = DateUtil.endOfMonth(new Date()); |
| | | // 获取用户的所有签到记录 |
| | | List<TAppUserSign> signRecords = signService.lambdaQuery() |
| | | .between(TAppUserSign::getSignDay, startOfMonth, endOfMonth) |
| | | .eq(TAppUserSign::getAppUserId, userId) |
| | | .orderByDesc(TAppUserSign::getSignDay) |
| | | .list(); |
| | | |
| | | // 如果没有签到记录,则返回0 |
| | | if (signRecords.isEmpty()) { |
| | | return 0; |
| | | } |
| | | |
| | | // 将签到日期转换为 LocalDate 列表,并按照日期排序 |
| | | List<LocalDate> signDays = signRecords.stream() |
| | | .map(TAppUserSign::getSignDay) |
| | | .sorted() |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 计算连续签到的最大天数 |
| | | return calculateMaxContinuousSignDays(signDays); |
| | | } |
| | | |
| | | /** |
| | | * 根据签到日期列表计算连续签到的最大天数 |
| | | * @param signDays 签到日期列表 |
| | | * @return 最大连续签到天数 |
| | | */ |
| | | private int calculateMaxContinuousSignDays(List<LocalDate> signDays) { |
| | | int maxContinuousDays = 0; |
| | | int currentContinuousDays = 0; |
| | | LocalDate lastSignDay = null; |
| | | |
| | | for (LocalDate signDay : signDays) { |
| | | if (lastSignDay != null && signDay.equals(lastSignDay.plusDays(1))) { |
| | | currentContinuousDays++; |
| | | } else { |
| | | maxContinuousDays = Math.max(maxContinuousDays, currentContinuousDays); |
| | | currentContinuousDays = 1; |
| | | } |
| | | lastSignDay = signDay; |
| | | } |
| | | |
| | | // 更新最后的连续天数 |
| | | maxContinuousDays = Math.max(maxContinuousDays, currentContinuousDays); |
| | | |
| | | return maxContinuousDays; |
| | | } |
| | | } |
| | |
| | | <result column="company_phone" property="companyPhone" /> |
| | | <result column="deposit_bank" property="depositBank" /> |
| | | <result column="bank_account" property="bankAccount" /> |
| | | <result column="default" property="default" /> |
| | | <result column="is_default" property="isDefault" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | id, app_user_id, invoice_type, invoicing_object_type, name, tax_identification_number, company_address, company_phone, deposit_bank, bank_account, default, create_time, del_flag |
| | | id, app_user_id, invoice_type, invoicing_object_type, name, tax_identification_number, company_address, company_phone, deposit_bank, bank_account, is_default, create_time, del_flag |
| | | </sql> |
| | | |
| | | </mapper> |
New file |
| | |
| | | package com.ruoyi.chargingPile.controller; |
| | | |
| | | import com.ruoyi.account.api.feignClient.AppUserClient; |
| | | import com.ruoyi.account.api.model.TAppUser; |
| | | import com.ruoyi.chargingPile.api.model.TChargingPile; |
| | | import com.ruoyi.chargingPile.service.TChargingPileNotificationService; |
| | | import com.ruoyi.common.core.constant.Constants; |
| | | import com.ruoyi.common.core.constant.MsgConstants; |
| | | import com.ruoyi.common.core.utils.HttpUtils; |
| | | import com.ruoyi.common.core.utils.MsgUtil; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.common.redis.service.RedisService; |
| | | 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.RequestParam; |
| | | |
| | | import java.util.Objects; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | public class CodeController { |
| | | |
| | | @Autowired |
| | | private RedisService redisService; |
| | | @Autowired |
| | | private AppUserClient appUserClient; |
| | | @Autowired |
| | | private TChargingPileNotificationService chargingPileNotificationService; |
| | | |
| | | /** |
| | | * 获取验证码 |
| | | * |
| | | * @param phone 手机号 |
| | | * @return 结果 |
| | | */ |
| | | @ApiOperation(value = "获取验证码",notes = "获取验证码",tags = {"更换手机号获取验证码"}) |
| | | @GetMapping("getCode") |
| | | public AjaxResult getCode(@RequestParam("phone") String phone) |
| | | { |
| | | TAppUser appUser = appUserClient.selectByPhone(phone).getData(); |
| | | if (Objects.nonNull(appUser)){ |
| | | return AjaxResult.error("该手机号已绑定账号"); |
| | | } |
| | | String code = MsgUtil.createCode(); |
| | | redisService.setCacheObject(phone+ Constants.APPLET,code,5L, TimeUnit.MINUTES); |
| | | String reqStr = MsgUtil.codeMsg(phone, code); |
| | | String result = HttpUtils.post(MsgConstants.SEND_URL, reqStr); |
| | | // 记录短信发送 |
| | | chargingPileNotificationService.saveData(1,null,null,phone,"验证码:"+code+",用于更换手机号。请勿转发。"); |
| | | return AjaxResult.success(result); |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/getSiteList") |
| | | @PostMapping("/addSite") |
| | | @ApiOperation(value = "添加站点", tags = {"管理后台-站点管理"}) |
| | | public AjaxResult addSite(@RequestBody Site site){ |
| | | return siteService.addSite(site); |
| | |
| | | @Log(title = "添加故障报修管理", businessType = BusinessType.INSERT,operatorType = OperatorType.MOBILE) |
| | | @ApiOperation(tags = {"小程序-故障报修"},value = "添加故障报修管理") |
| | | @PostMapping(value = "/add") |
| | | public AjaxResult<Boolean> add(@Validated @RequestBody TFaultMessage dto) { |
| | | return AjaxResult.ok(faultMessageService.save(dto)); |
| | | public AjaxResult<String> add(@Validated @RequestBody TFaultMessage dto) { |
| | | faultMessageService.add(dto); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | |
| | | * @return |
| | | */ |
| | | PageInfo<TChargingPileNotification> chargingPileNotificationPageList(Integer siteId, BasePage basePage); |
| | | |
| | | /** |
| | | * |
| | | * @param type 1=验证码 2=停车占位 3=充电结束 4=桩故障 |
| | | * @param phone 手机号 |
| | | * @param data 内容 |
| | | */ |
| | | void saveData(Integer type,Integer siteId,Integer chargingPileId, String phone, String data); |
| | | |
| | | } |
| | |
| | | */ |
| | | public interface TFaultMessageService extends IService<TFaultMessage> { |
| | | |
| | | /** |
| | | * 添加故障报修管理 |
| | | * @param dto |
| | | * @return |
| | | */ |
| | | void add(TFaultMessage dto); |
| | | } |
| | |
| | | pageInfo.setRecords(list); |
| | | return pageInfo; |
| | | } |
| | | |
| | | @Override |
| | | public void saveData(Integer type,Integer siteId,Integer chargingPileId, String phone, String data) { |
| | | TChargingPileNotification notification = new TChargingPileNotification(); |
| | | switch (type){ |
| | | case 1: |
| | | // 验证码 |
| | | notification.setPhone(phone); |
| | | notification.setContent(data); |
| | | break; |
| | | default: |
| | | // 停车占位 |
| | | notification.setSiteId(siteId); |
| | | notification.setChargingPileId(chargingPileId); |
| | | notification.setPhone(phone); |
| | | notification.setContent(data); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | package com.ruoyi.chargingPile.service.impl; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.chargingPile.api.model.Site; |
| | | import com.ruoyi.chargingPile.api.model.TChargingPile; |
| | | import com.ruoyi.chargingPile.api.model.TFaultMessage; |
| | | import com.ruoyi.chargingPile.mapper.TFaultMessageMapper; |
| | | import com.ruoyi.chargingPile.service.ISiteService; |
| | | import com.ruoyi.chargingPile.service.TChargingPileNotificationService; |
| | | import com.ruoyi.chargingPile.service.TChargingPileService; |
| | | import com.ruoyi.chargingPile.service.TFaultMessageService; |
| | | import com.ruoyi.common.core.utils.MsgUtil; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | |
| | | * @author xiaochen |
| | | * @since 2024-08-08 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class TFaultMessageServiceImpl extends ServiceImpl<TFaultMessageMapper, TFaultMessage> implements TFaultMessageService { |
| | | |
| | | @Autowired |
| | | private ISiteService siteService; |
| | | @Autowired |
| | | private TChargingPileService chargingPileService; |
| | | @Autowired |
| | | private TChargingPileNotificationService chargingPileNotificationService; |
| | | |
| | | @Override |
| | | public void add(TFaultMessage dto) { |
| | | // 故障短信提醒 |
| | | Site site = siteService.getById(dto.getSiteId()); |
| | | TChargingPile chargingPile = chargingPileService.getById(dto.getChargingPileId()); |
| | | String siteName = site.getName(); |
| | | String result = MsgUtil.faultMsg(site.getPhone(), site.getName(), chargingPile.getNumber() + ""); |
| | | log.info("故障短信提醒:{}",result); |
| | | if(siteName.length()>10){ |
| | | siteName = siteName.substring(0,10); |
| | | } |
| | | chargingPileNotificationService.saveData(4,dto.getSiteId(),dto.getChargingPileId(),site.getPhone(),"检测到"+siteName+"..."+chargingPile.getNumber()+"号桩设备离线,请及时查看处理!"); |
| | | this.save(dto); |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.order.api.model.TOrderEvaluate; |
| | | import com.ruoyi.order.api.query.TChargingCountQuery; |
| | | import com.ruoyi.order.dto.GetMyChargingOrderList; |
| | | import com.ruoyi.order.dto.GetNoInvoicedOrder; |
| | | import com.ruoyi.order.dto.MyChargingOrderInfo; |
| | | import com.ruoyi.order.dto.MyChargingOrderList; |
| | | import com.ruoyi.order.dto.OrderEvaluateVo; |
| | | import com.ruoyi.order.service.TChargingOrderService; |
| | | import com.ruoyi.order.service.TOrderEvaluateService; |
| | |
| | | .eq(TChargingOrder::getDelFlag, 0).eq(TChargingOrder::getStatus, 3)); |
| | | return R.ok(one); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @GetMapping(value = "/getMyChargingOrderList") |
| | |
| | | MyChargingOrderInfo myChargingOrderInfo = chargingOrderService.getMyChargingOrderInfo(id); |
| | | return AjaxResult.success(myChargingOrderInfo); |
| | | } |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @GetMapping(value = "/getNoInvoicedOrder") |
| | | @ApiOperation(value = "获取未开票的订单数据", tags = {"小程序-充电发票"}) |
| | | public AjaxResult<List<MyChargingOrderList>> getNoInvoicedOrder(@RequestBody GetNoInvoicedOrder query){ |
| | | List<MyChargingOrderList> list = chargingOrderService.getNoInvoicedOrder(query); |
| | | return AjaxResult.success(list); |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | return AjaxResult.success(goodsExchangeOrder); |
| | | } |
| | | |
| | | |
| | | @PutMapping("/confirmReceipt/{id}") |
| | | @ApiOperation(value = "确认收货操作", tags = {"小程序-兑换记录"}) |
| | | public AjaxResult confirmReceipt(@PathVariable String id){ |
| | | TExchangeOrder tExchangeOrder = exchangeOrderService.getById(id); |
| | | if(tExchangeOrder.getStatus() == 3){ |
| | | return AjaxResult.error("不能重复确认收货"); |
| | | } |
| | | if(tExchangeOrder.getStatus() == 1){ |
| | | return AjaxResult.error("订单还未发货呢"); |
| | | } |
| | | if(tExchangeOrder.getStatus() == 4){ |
| | | return AjaxResult.error("订单已取消,不允许操作。"); |
| | | } |
| | | tExchangeOrder.setStatus(3); |
| | | exchangeOrderService.updateById(tExchangeOrder); |
| | | return AjaxResult.success(); |
| | | } |
| | | } |
| | | |
| | |
| | | package com.ruoyi.order.controller; |
| | | |
| | | |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.order.dto.AddOrderInvoice; |
| | | import com.ruoyi.order.dto.GetOrderInvoiceList; |
| | | import com.ruoyi.order.dto.MyOrderInvoiceInfo; |
| | | import com.ruoyi.order.dto.OrderInvoiceList; |
| | | import com.ruoyi.order.service.TOrderInvoiceService; |
| | | import io.swagger.annotations.Api; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @RequestMapping("/t-order-invoice") |
| | | public class TOrderInvoiceController { |
| | | |
| | | @Resource |
| | | private TOrderInvoiceService orderInvoiceService; |
| | | |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/addOrderInvoice") |
| | | @ApiOperation(value = "添加开票申请", tags = {"小程序-充电发票"}) |
| | | public AjaxResult addOrderInvoice(@RequestBody AddOrderInvoice addOrderInvoice){ |
| | | return orderInvoiceService.addOrderInvoice(addOrderInvoice); |
| | | } |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @GetMapping("/getMyOrderInvoiceList") |
| | | @ApiOperation(value = "获取开票记录列表", tags = {"小程序-充电发票"}) |
| | | public AjaxResult<List<OrderInvoiceList>> getMyOrderInvoiceList(GetOrderInvoiceList query){ |
| | | List<OrderInvoiceList> myOrderInvoiceList = orderInvoiceService.getMyOrderInvoiceList(query); |
| | | return AjaxResult.success(myOrderInvoiceList); |
| | | } |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @GetMapping("/getMyOrderInvoiceInfo/{id}") |
| | | @ApiOperation(value = "获取开票记录详情", tags = {"小程序-充电发票"}) |
| | | public AjaxResult<MyOrderInvoiceInfo> getMyOrderInvoiceInfo(@PathVariable String id){ |
| | | MyOrderInvoiceInfo myOrderInvoiceInfo = orderInvoiceService.getMyOrderInvoiceInfo(id); |
| | | return AjaxResult.success(myOrderInvoiceInfo); |
| | | } |
| | | } |
| | | |
| | |
| | | package com.ruoyi.order.controller; |
| | | |
| | | |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.order.api.model.TExchangeOrder; |
| | | import com.ruoyi.order.api.model.TShoppingOrder; |
| | | import com.ruoyi.order.dto.*; |
| | | import com.ruoyi.order.service.TShoppingOrderService; |
| | | import io.swagger.annotations.Api; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | @RestController |
| | | @RequestMapping("/t-shopping-order") |
| | | public class TShoppingOrderController { |
| | | |
| | | |
| | | @Resource |
| | | private TShoppingOrderService shoppingOrderService; |
| | | |
| | | |
| | | @GetMapping("/getMyShoppingOrderList") |
| | | @ApiOperation(value = "获取购买订单列表", tags = {"小程序-商城购买订单"}) |
| | | public AjaxResult<List<MyShoppingOrderList>> getMyShoppingOrderList(GetMyShoppingOrderList query){ |
| | | List<MyShoppingOrderList> list = shoppingOrderService.getMyShoppingOrderList(query); |
| | | return AjaxResult.success(list); |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/getMyShoppingOrderInfo/{id}") |
| | | @ApiOperation(value = "获取购买订单详情", tags = {"小程序-商城购买订单"}) |
| | | public AjaxResult<MyShoppingOrderInfo> getMyShoppingOrderInfo(@PathVariable String id){ |
| | | MyShoppingOrderInfo info = shoppingOrderService.getMyShoppingOrderInfo(id); |
| | | return AjaxResult.success(info); |
| | | } |
| | | |
| | | |
| | | |
| | | @PutMapping("/confirmReceipt/{id}") |
| | | @ApiOperation(value = "确认收货操作", tags = {"小程序-商城购买订单"}) |
| | | public AjaxResult confirmReceipt(@PathVariable String id){ |
| | | TShoppingOrder shoppingOrder = shoppingOrderService.getById(id); |
| | | if(shoppingOrder.getStatus() == 3){ |
| | | return AjaxResult.error("不能重复确认收货"); |
| | | } |
| | | if(shoppingOrder.getStatus() == 1){ |
| | | return AjaxResult.error("订单还未发货呢"); |
| | | } |
| | | if(shoppingOrder.getStatus() == 4){ |
| | | return AjaxResult.error("订单已取消,不允许操作。"); |
| | | } |
| | | shoppingOrder.setStatus(3); |
| | | shoppingOrderService.updateById(shoppingOrder); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | @PutMapping("/cancelOrder/{id}") |
| | | @ApiOperation(value = "取消订单操作", tags = {"小程序-商城购买订单"}) |
| | | public AjaxResult cancelOrder(@PathVariable String id){ |
| | | return shoppingOrderService.cancelOrder(id); |
| | | } |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @GetMapping(value = "/getNoInvoicedOrder") |
| | | @ApiOperation(value = "获取未开票的订单数据", tags = {"小程序-充电发票"}) |
| | | public AjaxResult<List<MyShoppingOrderList>> getNoInvoicedOrder(GetNoInvoicedOrder query){ |
| | | List<MyShoppingOrderList> list = shoppingOrderService.getNoInvoicedOrder(query); |
| | | return AjaxResult.success(list); |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | package com.ruoyi.order.dto; |
| | | |
| | | import com.ruoyi.order.api.model.TOrderInvoice; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2024/8/19 15:29 |
| | | */ |
| | | @Data |
| | | @ApiModel |
| | | public class AddOrderInvoice extends TOrderInvoice { |
| | | @ApiModelProperty("订单数据数组[{\"id\":111,\"amount\":30}]") |
| | | private String orders; |
| | | } |
New file |
| | |
| | | package com.ruoyi.order.dto; |
| | | |
| | | import com.ruoyi.common.core.web.page.BasePage; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2024/8/19 13:43 |
| | | */ |
| | | @Data |
| | | @ApiModel |
| | | public class GetMyShoppingOrderList extends BasePage { |
| | | @ApiModelProperty(value = "状态(0=全部,1=待发货,2=待收货,3=已完成)") |
| | | private Integer status; |
| | | } |
New file |
| | |
| | | package com.ruoyi.order.dto; |
| | | |
| | | import com.ruoyi.common.core.web.page.BasePage; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2024/8/19 14:33 |
| | | */ |
| | | @Data |
| | | @ApiModel |
| | | public class GetNoInvoicedOrder extends BasePage { |
| | | @ApiModelProperty("日期") |
| | | private String month; |
| | | } |
New file |
| | |
| | | package com.ruoyi.order.dto; |
| | | |
| | | import com.ruoyi.common.core.web.page.BasePage; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2024/8/19 16:17 |
| | | */ |
| | | @Data |
| | | @ApiModel |
| | | public class GetOrderInvoiceList extends BasePage { |
| | | @ApiModelProperty("状态(1=已申请,2=开票中,3=开票成功)") |
| | | private Integer status; |
| | | } |
New file |
| | |
| | | package com.ruoyi.order.dto; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2024/8/19 16:58 |
| | | */ |
| | | @Data |
| | | @ApiModel |
| | | public class MyOrderInvoiceInfo { |
| | | @ApiModelProperty("订单id") |
| | | private String id; |
| | | @ApiModelProperty("订单号") |
| | | private String code; |
| | | @ApiModelProperty("发票类型") |
| | | private String invoiceType; |
| | | @ApiModelProperty("开票订单类型(1=充电订单,2=购物订单,3=兑换订单,4=会员订单)") |
| | | private Integer orderType; |
| | | @ApiModelProperty("抬头类型(1=个人,2=企业)") |
| | | private Integer invoicingObjectType; |
| | | @ApiModelProperty("发票金额") |
| | | private BigDecimal totalAmount; |
| | | @ApiModelProperty("电子发票地址") |
| | | private String invoiceUrl; |
| | | @ApiModelProperty(value = "状态(1=待开票,2=开票中,3=已开票)") |
| | | private Integer status; |
| | | @ApiModelProperty("关联订单(商城订单)") |
| | | private List<MyShoppingOrderList> shoppingOrder; |
| | | @ApiModelProperty("关联订单(充电订单)") |
| | | private List<MyChargingOrderList> chargingOrder; |
| | | } |
New file |
| | |
| | | package com.ruoyi.order.dto; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2024/8/19 14:04 |
| | | */ |
| | | @Data |
| | | @ApiModel |
| | | public class MyShoppingOrderInfo { |
| | | @ApiModelProperty("订单id") |
| | | private String id; |
| | | @ApiModelProperty("状态(1=待发货,2=待收货,3=已完成,4=已取消)") |
| | | private Integer status; |
| | | @ApiModelProperty("收货人姓名") |
| | | private String consignee; |
| | | @ApiModelProperty("电话") |
| | | private String phone; |
| | | @ApiModelProperty("地址") |
| | | private String address; |
| | | @ApiModelProperty("快递公司") |
| | | private String expressCompany; |
| | | @ApiModelProperty("快递单号") |
| | | private String expressNumber; |
| | | @ApiModelProperty("商品名称") |
| | | private String name; |
| | | @ApiModelProperty("商品图片") |
| | | private String imgUrl; |
| | | @ApiModelProperty("数量") |
| | | private Integer number; |
| | | @ApiModelProperty("单价") |
| | | private BigDecimal unitPrice; |
| | | @ApiModelProperty("订单编号") |
| | | private String code; |
| | | @ApiModelProperty("下单时间") |
| | | private String createTime; |
| | | @ApiModelProperty("支付金额") |
| | | private BigDecimal paymentAmount; |
| | | @ApiModelProperty("备注") |
| | | private String remark; |
| | | @ApiModelProperty("发货时间") |
| | | private String deliveryTime; |
| | | @ApiModelProperty("完成时间") |
| | | private String finishTime; |
| | | @ApiModelProperty("优惠券类型(1=充电优惠券,2=购物优惠券)") |
| | | private Integer couponType; |
| | | @ApiModelProperty("优惠券有效天数") |
| | | private Integer days; |
| | | @ApiModelProperty("有效期截止时间") |
| | | private String endTime; |
| | | } |
New file |
| | |
| | | package com.ruoyi.order.dto; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2024/8/19 13:45 |
| | | */ |
| | | @Data |
| | | @ApiModel |
| | | public class MyShoppingOrderList { |
| | | @ApiModelProperty(value = "订单id") |
| | | private String id; |
| | | @ApiModelProperty("封面图") |
| | | private String imgUrl; |
| | | @ApiModelProperty("商品名称") |
| | | private String name; |
| | | @ApiModelProperty("状态(1=待发货,2=待收货,3=已完成,4=已取消)") |
| | | private Integer status; |
| | | @ApiModelProperty("单价") |
| | | private BigDecimal unitPrice; |
| | | @ApiModelProperty("数量") |
| | | private Integer number; |
| | | @ApiModelProperty("支付金额") |
| | | private BigDecimal paymentAmount; |
| | | } |
New file |
| | |
| | | package com.ruoyi.order.dto; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2024/8/19 16:18 |
| | | */ |
| | | @Data |
| | | @ApiModel |
| | | public class OrderInvoiceList { |
| | | @ApiModelProperty("数据id") |
| | | private String id; |
| | | @ApiModelProperty("订单类型(1=充电订单,2=购物订单,3=兑换订单,4=会员订单)") |
| | | private Integer orderType; |
| | | @ApiModelProperty("开票金额") |
| | | private BigDecimal totalAmount; |
| | | @ApiModelProperty("抬头名称") |
| | | private String name; |
| | | @ApiModelProperty("申请时间") |
| | | private String createTime; |
| | | } |
| | |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ruoyi.order.api.model.TChargingOrder; |
| | | import com.ruoyi.order.dto.GetNoInvoicedOrder; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | * @param pageSize |
| | | * @return |
| | | */ |
| | | List<TChargingOrder> getMyChargingOrderList(Long appUserId, Integer type, Integer pageCurr, Integer pageSize); |
| | | List<TChargingOrder> getMyChargingOrderList(@Param("appUserId") Long appUserId, @Param("type") Integer type, |
| | | @Param("pageCurr") Integer pageCurr, @Param("pageSize") Integer pageSize); |
| | | |
| | | |
| | | /** |
| | | * 获取待开票订单列表 |
| | | * @param month 筛选时间2024-01-01 |
| | | * @param pageCurr |
| | | * @param pageSize |
| | | * @return |
| | | */ |
| | | List<TChargingOrder> getNoInvoicedOrder(@Param("appUserId") Long appUserId, @Param("month") String month, |
| | | @Param("pageCurr") Integer pageCurr, @Param("pageSize") Integer pageSize); |
| | | } |
| | |
| | | public interface TShoppingOrderMapper extends BaseMapper<TShoppingOrder> { |
| | | |
| | | List<TActivityStatisticslVO> activityStatistics(@Param("pageInfo") PageInfo<TActivityStatisticslVO> pageInfo, @Param("req")TActivityStatisticsQuery dto); |
| | | |
| | | |
| | | /** |
| | | * 获取未开票的订单数据 |
| | | * @param appUserId |
| | | * @param month |
| | | * @param pageCurr |
| | | * @param pageSize |
| | | * @return |
| | | */ |
| | | List<TShoppingOrder> getNoInvoicedOrder(@Param("appUserId") Long appUserId, @Param("month") String month, |
| | | @Param("pageCurr") Integer pageCurr, @Param("pageSize") Integer pageSize); |
| | | } |
| | |
| | | import com.ruoyi.common.core.web.page.BasePage; |
| | | import com.ruoyi.order.api.model.TChargingOrder; |
| | | import com.ruoyi.order.dto.GetMyChargingOrderList; |
| | | import com.ruoyi.order.dto.GetNoInvoicedOrder; |
| | | import com.ruoyi.order.dto.MyChargingOrderInfo; |
| | | import com.ruoyi.order.dto.MyChargingOrderList; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | |
| | | * @return |
| | | */ |
| | | MyChargingOrderInfo getMyChargingOrderInfo(String id); |
| | | |
| | | |
| | | /** |
| | | * 获取待开票订单列表 |
| | | * @param query |
| | | * @return |
| | | */ |
| | | List<MyChargingOrderList> getNoInvoicedOrder(GetNoInvoicedOrder query); |
| | | } |
| | |
| | | package com.ruoyi.order.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.order.api.model.TOrderInvoice; |
| | | import com.ruoyi.order.dto.AddOrderInvoice; |
| | | import com.ruoyi.order.dto.GetOrderInvoiceList; |
| | | import com.ruoyi.order.dto.MyOrderInvoiceInfo; |
| | | import com.ruoyi.order.dto.OrderInvoiceList; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | * @since 2024-08-07 |
| | | */ |
| | | public interface TOrderInvoiceService extends IService<TOrderInvoice> { |
| | | |
| | | |
| | | |
| | | /** |
| | | * 添加开票申请 |
| | | * @param addOrderInvoice |
| | | * @return |
| | | */ |
| | | AjaxResult addOrderInvoice(AddOrderInvoice addOrderInvoice); |
| | | |
| | | |
| | | /** |
| | | * 获取小程序用户开票记录 |
| | | * @param query |
| | | * @return |
| | | */ |
| | | List<OrderInvoiceList> getMyOrderInvoiceList(GetOrderInvoiceList query); |
| | | |
| | | |
| | | /** |
| | | * 获取开票申请详情 |
| | | * @param id |
| | | * @return |
| | | */ |
| | | MyOrderInvoiceInfo getMyOrderInvoiceInfo(String id); |
| | | } |
| | |
| | | package com.ruoyi.order.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import com.ruoyi.order.api.model.TShoppingOrder; |
| | | import com.ruoyi.order.api.query.TActivityStatisticsQuery; |
| | | import com.ruoyi.order.api.vo.TActivityStatisticslVO; |
| | | import com.ruoyi.order.api.vo.TActivityVO; |
| | | import com.ruoyi.order.dto.GetMyShoppingOrderList; |
| | | import com.ruoyi.order.dto.GetNoInvoicedOrder; |
| | | import com.ruoyi.order.dto.MyShoppingOrderInfo; |
| | | import com.ruoyi.order.dto.MyShoppingOrderList; |
| | | import org.springframework.web.bind.annotation.PathVariable; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | public interface TShoppingOrderService extends IService<TShoppingOrder> { |
| | | |
| | | TActivityVO activityStatistics(TActivityStatisticsQuery dto); |
| | | |
| | | |
| | | /** |
| | | * 获取小程序商城购买订单列表 |
| | | * @param query |
| | | * @return |
| | | */ |
| | | List<MyShoppingOrderList> getMyShoppingOrderList(GetMyShoppingOrderList query); |
| | | |
| | | |
| | | /** |
| | | * 获取购买订单详情 |
| | | * @param id |
| | | * @return |
| | | */ |
| | | MyShoppingOrderInfo getMyShoppingOrderInfo(String id); |
| | | |
| | | |
| | | /** |
| | | * 取消订单 |
| | | * @param id |
| | | * @return |
| | | */ |
| | | AjaxResult cancelOrder(String id); |
| | | |
| | | |
| | | /** |
| | | * 获取未开票的订单列表 |
| | | * @param query |
| | | * @return |
| | | */ |
| | | List<MyShoppingOrderList> getNoInvoicedOrder(GetNoInvoicedOrder query); |
| | | } |
| | |
| | | import com.ruoyi.order.api.model.TChargingOrder; |
| | | import com.ruoyi.order.api.model.TChargingOrderAccountingStrategy; |
| | | import com.ruoyi.order.dto.GetMyChargingOrderList; |
| | | import com.ruoyi.order.dto.GetNoInvoicedOrder; |
| | | import com.ruoyi.order.dto.MyChargingOrderInfo; |
| | | import com.ruoyi.order.dto.MyChargingOrderList; |
| | | import com.ruoyi.order.mapper.TChargingOrderMapper; |
| | |
| | | myChargingOrderInfo.setActionable(myChargingOrderInfo.getEndTime() + 604800000L > System.currentTimeMillis() ? 0 : 1); |
| | | return myChargingOrderInfo; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取待开票订单列表 |
| | | * @param query |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<MyChargingOrderList> getNoInvoicedOrder(GetNoInvoicedOrder query) { |
| | | Long appUserId = tokenService.getLoginUserApplet().getUserId(); |
| | | List<TChargingOrder> orderList = this.baseMapper.getNoInvoicedOrder(appUserId, query.getMonth(), query.getPageCurr(), query.getPageSize()); |
| | | List<MyChargingOrderList> list = new ArrayList<>(); |
| | | for (TChargingOrder tChargingOrder : orderList) { |
| | | MyChargingOrderList myChargingOrderList = new MyChargingOrderList(); |
| | | myChargingOrderList.setId(tChargingOrder.getId().toString()); |
| | | myChargingOrderList.setStatus(tChargingOrder.getStatus()); |
| | | Site site = siteClient.getSiteByIds(Arrays.asList(tChargingOrder.getSiteId())).getData().get(0); |
| | | myChargingOrderList.setTitle(site.getName()); |
| | | myChargingOrderList.setChargingDegree(tChargingOrder.getChargingCapacity()); |
| | | String name = chargingGunClient.getAllName(tChargingOrder.getChargingGunId()).getData(); |
| | | myChargingOrderList.setName(name); |
| | | myChargingOrderList.setEndMode(tChargingOrder.getEndMode()); |
| | | BigDecimal payMoney = tChargingOrder.getStatus() < 4 ? tChargingOrder.getRechargeAmount() : tChargingOrder.getPaymentAmount(); |
| | | myChargingOrderList.setPayMoney(payMoney); |
| | | myChargingOrderList.setCreateTime(tChargingOrder.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| | | list.add(myChargingOrderList); |
| | | } |
| | | return list; |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.order.service.impl; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONArray; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient; |
| | | import com.ruoyi.chargingPile.api.feignClient.SiteClient; |
| | | import com.ruoyi.chargingPile.api.model.Site; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import com.ruoyi.order.api.model.TChargingOrder; |
| | | import com.ruoyi.order.api.model.TOrderInvoice; |
| | | import com.ruoyi.order.api.model.TOrderInvoiceDetail; |
| | | import com.ruoyi.order.api.model.TShoppingOrder; |
| | | import com.ruoyi.order.dto.*; |
| | | import com.ruoyi.order.mapper.TOrderInvoiceMapper; |
| | | import com.ruoyi.order.service.TChargingOrderService; |
| | | import com.ruoyi.order.service.TOrderInvoiceDetailService; |
| | | import com.ruoyi.order.service.TOrderInvoiceService; |
| | | import com.ruoyi.order.service.TShoppingOrderService; |
| | | import com.ruoyi.other.api.domain.TCoupon; |
| | | import com.ruoyi.other.api.domain.TGoods; |
| | | import com.ruoyi.other.api.domain.TInvoiceType; |
| | | import com.ruoyi.other.api.feignClient.CouponClient; |
| | | import com.ruoyi.other.api.feignClient.GoodsClient; |
| | | import com.ruoyi.other.api.feignClient.InvoiceTypeClient; |
| | | import io.seata.spring.annotation.GlobalTransactional; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | */ |
| | | @Service |
| | | public class TOrderInvoiceServiceImpl extends ServiceImpl<TOrderInvoiceMapper, TOrderInvoice> implements TOrderInvoiceService { |
| | | |
| | | |
| | | @Resource |
| | | private TokenService tokenService; |
| | | |
| | | @Resource |
| | | private TOrderInvoiceDetailService orderInvoiceDetailService; |
| | | |
| | | @Resource |
| | | private InvoiceTypeClient invoiceTypeClient; |
| | | |
| | | @Resource |
| | | private TChargingOrderService chargingOrderService; |
| | | |
| | | @Resource |
| | | private TShoppingOrderService shoppingOrderService; |
| | | |
| | | @Resource |
| | | private ChargingGunClient chargingGunClient; |
| | | |
| | | @Resource |
| | | private SiteClient siteClient; |
| | | |
| | | @Resource |
| | | private GoodsClient goodsClient; |
| | | |
| | | @Resource |
| | | private CouponClient couponClient; |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 添加开票申请 |
| | | * @param addOrderInvoice |
| | | * @return |
| | | */ |
| | | @Override |
| | | @GlobalTransactional(rollbackFor = Exception.class) |
| | | public AjaxResult addOrderInvoice(AddOrderInvoice addOrderInvoice) { |
| | | Long userId = tokenService.getLoginUserApplet().getUserId(); |
| | | String orders = addOrderInvoice.getOrders(); |
| | | if(StringUtils.isNotEmpty(orders)){ |
| | | return AjaxResult.error("请选择有效的订单"); |
| | | } |
| | | JSONArray parse = JSONArray.parse(orders); |
| | | List<Long> orderIds = new ArrayList<>(); |
| | | Map<Long, BigDecimal> map = new HashMap<>(); |
| | | for (int i = 0; i < parse.size(); i++) { |
| | | JSONObject jsonObject = parse.getJSONObject(i); |
| | | Long id = jsonObject.getLong("id"); |
| | | BigDecimal amount = jsonObject.getBigDecimal("amount"); |
| | | orderIds.add(id); |
| | | map.put(id, amount); |
| | | } |
| | | long count = orderInvoiceDetailService.count(new LambdaQueryWrapper<TOrderInvoiceDetail>().eq(TOrderInvoiceDetail::getOrderType, addOrderInvoice.getOrderType()) |
| | | .in(TOrderInvoiceDetail::getOrderId, orderIds)); |
| | | if(count > 0){ |
| | | return AjaxResult.error("不能重复申请开票,请刷新数据后重试"); |
| | | } |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); |
| | | String code = Math.random() * 1000 + sdf.format(new Date()); |
| | | addOrderInvoice.setAppUserId(userId); |
| | | addOrderInvoice.setCode(code); |
| | | addOrderInvoice.setStatus(1); |
| | | this.save(addOrderInvoice); |
| | | //获取开票类型 |
| | | TInvoiceType invoiceType = invoiceTypeClient.getInvoiceType(addOrderInvoice.getInvoiceTypeId()).getData(); |
| | | for (Long orderId : orderIds) { |
| | | TOrderInvoiceDetail orderInvoiceDetail = new TOrderInvoiceDetail(); |
| | | orderInvoiceDetail.setOrderInvoiceId(addOrderInvoice.getId()); |
| | | orderInvoiceDetail.setInvoiceAmount(map.get(orderId)); |
| | | orderInvoiceDetail.setOrderType(addOrderInvoice.getOrderType()); |
| | | orderInvoiceDetail.setOrderId(orderId); |
| | | orderInvoiceDetail.setElectricityTariff(invoiceType.getElectricityTariff()); |
| | | orderInvoiceDetail.setServiceTariff(invoiceType.getServiceTariff()); |
| | | orderInvoiceDetail.setAddedServiceTariff(invoiceType.getAddedServiceTariff()); |
| | | orderInvoiceDetailService.save(orderInvoiceDetail); |
| | | } |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取开票记录列表 |
| | | * @param query |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<OrderInvoiceList> getMyOrderInvoiceList(GetOrderInvoiceList query) { |
| | | Long userId = tokenService.getLoginUserApplet().getUserId(); |
| | | List<TOrderInvoice> list = this.list(new LambdaQueryWrapper<TOrderInvoice>().eq(TOrderInvoice::getAppUserId, userId) |
| | | .eq(TOrderInvoice::getStatus, query.getStatus()).orderByDesc(TOrderInvoice::getCreateTime) |
| | | .last(" limit " + query.getPageCurr() + ", " + query.getPageSize())); |
| | | List<OrderInvoiceList> pageList = new ArrayList<>(); |
| | | for (TOrderInvoice tOrderInvoice : list) { |
| | | OrderInvoiceList orderInvoiceList = new OrderInvoiceList(); |
| | | orderInvoiceList.setId(tOrderInvoice.getId().toString()); |
| | | orderInvoiceList.setOrderType(tOrderInvoice.getOrderType()); |
| | | orderInvoiceList.setTotalAmount(tOrderInvoice.getTotalAmount()); |
| | | orderInvoiceList.setName(tOrderInvoice.getName()); |
| | | orderInvoiceList.setCreateTime(tOrderInvoice.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| | | pageList.add(orderInvoiceList); |
| | | } |
| | | return pageList; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取开票申请详情 |
| | | * @param id |
| | | * @return |
| | | */ |
| | | @Override |
| | | public MyOrderInvoiceInfo getMyOrderInvoiceInfo(String id) { |
| | | TOrderInvoice orderInvoice = this.getById(id); |
| | | MyOrderInvoiceInfo myOrderInvoiceInfo = new MyOrderInvoiceInfo(); |
| | | myOrderInvoiceInfo.setId(id); |
| | | myOrderInvoiceInfo.setCode(orderInvoice.getCode()); |
| | | myOrderInvoiceInfo.setInvoiceType(orderInvoice.getInvoiceType()); |
| | | myOrderInvoiceInfo.setOrderType(orderInvoice.getOrderType()); |
| | | myOrderInvoiceInfo.setInvoicingObjectType(orderInvoice.getInvoicingObjectType()); |
| | | myOrderInvoiceInfo.setTotalAmount(orderInvoice.getTotalAmount()); |
| | | myOrderInvoiceInfo.setInvoiceUrl(orderInvoice.getInvoiceUrl()); |
| | | myOrderInvoiceInfo.setStatus(orderInvoice.getStatus()); |
| | | Integer orderType = orderInvoice.getOrderType(); |
| | | List<TOrderInvoiceDetail> list = orderInvoiceDetailService.list(new LambdaQueryWrapper<TOrderInvoiceDetail>().eq(TOrderInvoiceDetail::getOrderInvoiceId, id)); |
| | | List<Long> orderIds = list.stream().map(TOrderInvoiceDetail::getOrderId).collect(Collectors.toList()); |
| | | //充电订单 |
| | | if(orderType == 1){ |
| | | List<TChargingOrder> orderList = chargingOrderService.listByIds(orderIds); |
| | | List<MyChargingOrderList> chargingOrder = new ArrayList<>(); |
| | | for (TChargingOrder tChargingOrder : orderList) { |
| | | MyChargingOrderList myChargingOrderList = new MyChargingOrderList(); |
| | | myChargingOrderList.setId(tChargingOrder.getId().toString()); |
| | | myChargingOrderList.setStatus(tChargingOrder.getStatus()); |
| | | Site site = siteClient.getSiteByIds(Arrays.asList(tChargingOrder.getSiteId())).getData().get(0); |
| | | myChargingOrderList.setTitle(site.getName()); |
| | | myChargingOrderList.setChargingDegree(tChargingOrder.getChargingCapacity()); |
| | | String name = chargingGunClient.getAllName(tChargingOrder.getChargingGunId()).getData(); |
| | | myChargingOrderList.setName(name); |
| | | myChargingOrderList.setEndMode(tChargingOrder.getEndMode()); |
| | | BigDecimal payMoney = tChargingOrder.getStatus() < 4 ? tChargingOrder.getRechargeAmount() : tChargingOrder.getPaymentAmount(); |
| | | myChargingOrderList.setPayMoney(payMoney); |
| | | myChargingOrderList.setCreateTime(tChargingOrder.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| | | chargingOrder.add(myChargingOrderList); |
| | | } |
| | | myOrderInvoiceInfo.setChargingOrder(chargingOrder); |
| | | } |
| | | //购物订单 |
| | | if(orderType == 2){ |
| | | List<TShoppingOrder> orderList = shoppingOrderService.listByIds(orderIds); |
| | | List<MyShoppingOrderList> shoppingOrder = new ArrayList<>(); |
| | | for (TShoppingOrder tShoppingOrder : orderList) { |
| | | MyShoppingOrderList myShoppingOrderList = new MyShoppingOrderList(); |
| | | myShoppingOrderList.setId(tShoppingOrder.getId().toString()); |
| | | String name = ""; |
| | | String imgUrl = ""; |
| | | if(tShoppingOrder.getOrderType() == 1){ |
| | | TGoods goods = goodsClient.getGoodsById(tShoppingOrder.getGoodsId()).getData(); |
| | | name = goods.getName(); |
| | | imgUrl = goods.getCoverPicture(); |
| | | }else{ |
| | | TCoupon coupon = couponClient.getCouponById1(tShoppingOrder.getGoodsId()).getData(); |
| | | name = coupon.getName(); |
| | | imgUrl = coupon.getCoverPicture(); |
| | | } |
| | | myShoppingOrderList.setName(name); |
| | | myShoppingOrderList.setImgUrl(imgUrl); |
| | | myShoppingOrderList.setStatus(tShoppingOrder.getStatus()); |
| | | BigDecimal unitPrice = tShoppingOrder.getPaymentAmount().divide(new BigDecimal(tShoppingOrder.getPurchaseQuantity())).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | myShoppingOrderList.setUnitPrice(unitPrice); |
| | | myShoppingOrderList.setNumber(tShoppingOrder.getPurchaseQuantity()); |
| | | myShoppingOrderList.setPaymentAmount(tShoppingOrder.getPaymentAmount()); |
| | | shoppingOrder.add(myShoppingOrderList); |
| | | } |
| | | myOrderInvoiceInfo.setShoppingOrder(shoppingOrder); |
| | | } |
| | | return myOrderInvoiceInfo; |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.order.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.account.api.feignClient.AppUserAddressClient; |
| | | import com.ruoyi.account.api.model.TAppUserAddress; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import com.ruoyi.order.api.model.TExchangeOrder; |
| | | import com.ruoyi.order.api.model.TShoppingOrder; |
| | | import com.ruoyi.order.api.query.TActivityStatisticsQuery; |
| | | import com.ruoyi.order.api.vo.TActivityStatisticslVO; |
| | | import com.ruoyi.order.api.vo.TActivityVO; |
| | | import com.ruoyi.order.dto.*; |
| | | import com.ruoyi.order.mapper.TShoppingOrderMapper; |
| | | import com.ruoyi.order.service.TShoppingOrderService; |
| | | import com.ruoyi.other.api.domain.TCoupon; |
| | | import com.ruoyi.other.api.domain.TGoods; |
| | | import com.ruoyi.other.api.feignClient.CouponClient; |
| | | import com.ruoyi.other.api.feignClient.GoodsClient; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.math.BigDecimal; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Service |
| | | public class TShoppingOrderServiceImpl extends ServiceImpl<TShoppingOrderMapper, TShoppingOrder> implements TShoppingOrderService { |
| | | |
| | | @Resource |
| | | private TokenService tokenService; |
| | | |
| | | @Resource |
| | | private GoodsClient goodsClient; |
| | | |
| | | @Resource |
| | | private CouponClient couponClient; |
| | | |
| | | @Resource |
| | | private AppUserAddressClient appUserAddressClient; |
| | | |
| | | |
| | | |
| | | |
| | | @Override |
| | | public TActivityVO activityStatistics(TActivityStatisticsQuery dto) { |
| | |
| | | res.setGrantVip(grantVip); |
| | | return res; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取小程序商城购买订单列表 |
| | | * @param query |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<MyShoppingOrderList> getMyShoppingOrderList(GetMyShoppingOrderList query) { |
| | | Long userId = tokenService.getLoginUserApplet().getUserId(); |
| | | LambdaQueryWrapper<TShoppingOrder> wrapper = new LambdaQueryWrapper<TShoppingOrder>().eq(TShoppingOrder::getDelFlag, 0) |
| | | .eq(TShoppingOrder::getAppUserId, userId); |
| | | if(query.getStatus() != 0){ |
| | | wrapper.eq(TShoppingOrder::getStatus, query.getStatus()); |
| | | } |
| | | List<TShoppingOrder> list = this.list(wrapper.orderByDesc(TShoppingOrder::getCreateTime).last(" limit " + query.getPageCurr() + ", " + query.getPageSize())); |
| | | List<MyShoppingOrderList> pageList = new ArrayList<>(); |
| | | for (TShoppingOrder tShoppingOrder : list) { |
| | | MyShoppingOrderList myShoppingOrderList = new MyShoppingOrderList(); |
| | | myShoppingOrderList.setId(tShoppingOrder.getId().toString()); |
| | | String name = ""; |
| | | String imgUrl = ""; |
| | | if(tShoppingOrder.getOrderType() == 1){ |
| | | TGoods goods = goodsClient.getGoodsById(tShoppingOrder.getGoodsId()).getData(); |
| | | name = goods.getName(); |
| | | imgUrl = goods.getCoverPicture(); |
| | | }else{ |
| | | TCoupon coupon = couponClient.getCouponById1(tShoppingOrder.getGoodsId()).getData(); |
| | | name = coupon.getName(); |
| | | imgUrl = coupon.getCoverPicture(); |
| | | } |
| | | myShoppingOrderList.setName(name); |
| | | myShoppingOrderList.setImgUrl(imgUrl); |
| | | myShoppingOrderList.setStatus(tShoppingOrder.getStatus()); |
| | | BigDecimal unitPrice = tShoppingOrder.getPaymentAmount().divide(new BigDecimal(tShoppingOrder.getPurchaseQuantity())).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | myShoppingOrderList.setUnitPrice(unitPrice); |
| | | myShoppingOrderList.setNumber(tShoppingOrder.getPurchaseQuantity()); |
| | | myShoppingOrderList.setPaymentAmount(tShoppingOrder.getPaymentAmount()); |
| | | pageList.add(myShoppingOrderList); |
| | | } |
| | | return pageList; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取购买订单详情 |
| | | * @param id |
| | | * @return |
| | | */ |
| | | @Override |
| | | public MyShoppingOrderInfo getMyShoppingOrderInfo(String id) { |
| | | TShoppingOrder shoppingOrder = this.getById(id); |
| | | MyShoppingOrderInfo info = new MyShoppingOrderInfo(); |
| | | info.setId(id); |
| | | info.setStatus(shoppingOrder.getStatus()); |
| | | TAppUserAddress userAddress = appUserAddressClient.getAppUserAddressById(shoppingOrder.getAppUserAddressId()).getData(); |
| | | info.setConsignee(userAddress.getName()); |
| | | info.setPhone(userAddress.getPhone()); |
| | | info.setAddress(userAddress.getAddress()); |
| | | info.setExpressCompany(shoppingOrder.getExpressCompany()); |
| | | info.setExpressNumber(shoppingOrder.getExpressNumber()); |
| | | String name = ""; |
| | | String imgUrl = ""; |
| | | if(shoppingOrder.getOrderType() == 1){ |
| | | TGoods goods = goodsClient.getGoodsById(shoppingOrder.getGoodsId()).getData(); |
| | | name = goods.getName(); |
| | | imgUrl = goods.getCoverPicture(); |
| | | }else{ |
| | | TCoupon coupon = couponClient.getCouponById1(shoppingOrder.getGoodsId()).getData(); |
| | | info.setCouponType(coupon.getType()); |
| | | info.setDays(coupon.getDays()); |
| | | info.setEndTime(coupon.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| | | name = coupon.getName(); |
| | | imgUrl = coupon.getCoverPicture(); |
| | | } |
| | | info.setName(name); |
| | | info.setImgUrl(imgUrl); |
| | | info.setNumber(shoppingOrder.getPurchaseQuantity()); |
| | | BigDecimal unitPrice = shoppingOrder.getPaymentAmount().divide(new BigDecimal(shoppingOrder.getPurchaseQuantity())).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | info.setUnitPrice(unitPrice); |
| | | info.setCode(shoppingOrder.getCode()); |
| | | info.setCreateTime(shoppingOrder.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| | | info.setPaymentAmount(shoppingOrder.getPaymentAmount()); |
| | | info.setRemark(shoppingOrder.getRemark()); |
| | | info.setDeliveryTime(shoppingOrder.getConsignerTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| | | info.setFinishTime(shoppingOrder.getReceivingTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
| | | return info; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 取消订单 |
| | | * @param id |
| | | * @return |
| | | */ |
| | | @Override |
| | | public AjaxResult cancelOrder(String id) { |
| | | TShoppingOrder shoppingOrder = this.getById(id); |
| | | if(shoppingOrder.getStatus() == 2){ |
| | | return AjaxResult.error("订单已发货,不能取消"); |
| | | } |
| | | if(shoppingOrder.getStatus() == 3){ |
| | | return AjaxResult.error("订单已完成,不能取消"); |
| | | } |
| | | if(shoppingOrder.getStatus() == 4){ |
| | | return AjaxResult.error("订单已取消,不能重复操作"); |
| | | } |
| | | //先查询第三方订单状态订单是否退款 |
| | | //支付方式(1=微信,2=支付宝) todo 待完善 |
| | | Integer paymentType = shoppingOrder.getPaymentType(); |
| | | if(1 == paymentType){ |
| | | |
| | | } |
| | | if(2 == paymentType){ |
| | | |
| | | } |
| | | //退款成功后需要判断商品库存类型后决定是否需要回退库存 |
| | | //加redis锁处理高并发 |
| | | |
| | | |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取未开票的订单列表 |
| | | * @param query |
| | | * @return |
| | | */ |
| | | @Override |
| | | public List<MyShoppingOrderList> getNoInvoicedOrder(GetNoInvoicedOrder query) { |
| | | Long userId = tokenService.getLoginUserApplet().getUserId(); |
| | | List<TShoppingOrder> list = this.baseMapper.getNoInvoicedOrder(userId, query.getMonth(), query.getPageCurr(), query.getPageSize()); |
| | | List<MyShoppingOrderList> pageList = new ArrayList<>(); |
| | | for (TShoppingOrder tShoppingOrder : list) { |
| | | MyShoppingOrderList myShoppingOrderList = new MyShoppingOrderList(); |
| | | myShoppingOrderList.setId(tShoppingOrder.getId().toString()); |
| | | String name = ""; |
| | | String imgUrl = ""; |
| | | if(tShoppingOrder.getOrderType() == 1){ |
| | | TGoods goods = goodsClient.getGoodsById(tShoppingOrder.getGoodsId()).getData(); |
| | | name = goods.getName(); |
| | | imgUrl = goods.getCoverPicture(); |
| | | }else{ |
| | | TCoupon coupon = couponClient.getCouponById1(tShoppingOrder.getGoodsId()).getData(); |
| | | name = coupon.getName(); |
| | | imgUrl = coupon.getCoverPicture(); |
| | | } |
| | | myShoppingOrderList.setName(name); |
| | | myShoppingOrderList.setImgUrl(imgUrl); |
| | | myShoppingOrderList.setStatus(tShoppingOrder.getStatus()); |
| | | BigDecimal unitPrice = tShoppingOrder.getPaymentAmount().divide(new BigDecimal(tShoppingOrder.getPurchaseQuantity())).setScale(2, BigDecimal.ROUND_HALF_EVEN); |
| | | myShoppingOrderList.setUnitPrice(unitPrice); |
| | | myShoppingOrderList.setNumber(tShoppingOrder.getPurchaseQuantity()); |
| | | myShoppingOrderList.setPaymentAmount(tShoppingOrder.getPaymentAmount()); |
| | | pageList.add(myShoppingOrderList); |
| | | } |
| | | return pageList; |
| | | } |
| | | } |
| | |
| | | limit #{pageCurr}, #{pageSize} |
| | | </if> |
| | | </select> |
| | | |
| | | |
| | | |
| | | <select id="getNoInvoicedOrder" resultMap="BaseResultMap"> |
| | | select * from t_charging_order where del_flag = 0 and app_user_id = #{appUserId} |
| | | <if test="null != month and '' != month"> |
| | | and DATE_FORMAT(end_time, '%Y-%m') = #{month} |
| | | </if> |
| | | and id not in (select order_id from t_order_invoice_detail where order_type = 1) |
| | | order by create_time desc |
| | | <if test="null != pageCurr and null != pageSize"> |
| | | limit #{pageCurr}, #{pageSize} |
| | | </if> |
| | | </select> |
| | | </mapper> |
| | |
| | | <result column="app_user_id" property="appUserId" /> |
| | | <result column="order_type" property="orderType" /> |
| | | <result column="invoicing_company" property="invoicingCompany" /> |
| | | <result column="invoice_type_id" property="invoiceTypeId"/> |
| | | <result column="invoice_type" property="invoiceType" /> |
| | | <result column="invoice_material" property="invoiceMaterial" /> |
| | | <result column="invoicing_method" property="invoicingMethod" /> |
| | |
| | | <result column="invoice_url" property="invoiceUrl" /> |
| | | <result column="mailbox" property="mailbox" /> |
| | | <result column="status" property="status" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="billing_time" property="billingTime" /> |
| | | <result column="billing_user_id" property="billingUserId" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | id, code, app_user_id, order_type, invoicing_company, invoice_type, invoice_material, invoicing_method, invoicing_object_type, name, tax_identification_number, company_address, company_phone, deposit_bank, bank_account, total_amount, invoice_url, mailbox, status |
| | | id, code, app_user_id, order_type, invoicing_company, invoice_type_id, invoice_type, invoice_material, invoicing_method, invoicing_object_type, name, tax_identification_number, company_address, company_phone, deposit_bank, bank_account, total_amount, invoice_url, mailbox, status, create_time, billing_time, billing_user_id |
| | | </sql> |
| | | |
| | | </mapper> |
| | |
| | | </if> |
| | | </if> |
| | | </select> |
| | | |
| | | |
| | | |
| | | |
| | | <select id="getNoInvoicedOrder" resultMap="BaseResultMap"> |
| | | select * from t_shopping_order where del_flag = 0 and app_user_id = #{appUserId} |
| | | <if test="null != month and '' != month"> |
| | | and DATE_FORMAT(create_time, '%Y-%m') = #{month} |
| | | </if> |
| | | and id not in (select order_id from t_order_invoice_detail where order_type = 2) |
| | | order by create_time desc |
| | | <if test="null != pageCurr and null != pageSize"> |
| | | limit #{pageCurr}, #{pageSize} |
| | | </if> |
| | | </select> |
| | | </mapper> |
| | |
| | | return AjaxResult.ok(activityService.getById(id)); |
| | | } |
| | | @ApiOperation(tags = {"管理后台-活动管理","小程序-个人中心-活动列表"},value = "活动列表分页查询") |
| | | |
| | | @PostMapping(value = "/pageList") |
| | | public AjaxResult<PageInfo<TActivity>> pageList(@RequestBody AdvertisingDTO dto) { |
| | | return AjaxResult.ok(activityService.pageList(dto)); |
| | |
| | | public class TActivityStatisticsController { |
| | | @Autowired |
| | | private OrderClient orderClient; |
| | | |
| | | |
| | | |
| | | @ApiOperation(tags = {"管理后台-活动费用统计"},value = "管理后台活动费用统计") |
| | | @PostMapping(value = "/pageList") |
| | | public AjaxResult<TActivityVO> pageList(@RequestBody TActivityStatisticsQuery query) { |
| | |
| | | public AjaxResult<TAdvertising> getInfo(Integer id) { |
| | | return AjaxResult.ok(advertisingService.getById(id)); |
| | | } |
| | | |
| | | |
| | | |
| | | @ApiOperation(tags = {"管理后台-广告管理"},value = "广告列表分页查询") |
| | | @PostMapping(value = "/pageList") |
| | | public AjaxResult<PageInfo<TAdvertising>> pageList(@RequestBody AdvertisingDTO dto) { |
| | |
| | | |
| | | @Autowired |
| | | private AppCouponClient appCouponClient; |
| | | |
| | | |
| | | @PostMapping("/saveGoods") |
| | | @ApiOperation(tags = {"管理后台-优惠券管理"},value = "优惠券添加") |
| | | public AjaxResult saveActivity(@RequestBody TCoupon dto) { |
| | | tCouponService.save(dto); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/delete") |
| | | @ApiOperation(tags = {"管理后台-优惠券管理"},value = "优惠券删除") |
| | | public AjaxResult delete(Integer id) { |
| | | tCouponService.removeById(id); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | @PostMapping("/updateVip") |
| | | @ApiOperation(tags = {"管理后台-优惠券管理"},value = "优惠券修改") |
| | | public AjaxResult updateActivity(@RequestBody TCoupon dto) { |
| | | tCouponService.updateById(dto); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/getInfo") |
| | | @ApiOperation(tags = {"管理后台-优惠券管理"},value = "优惠券查看详情") |
| | | public AjaxResult<TCoupon> getInfo(Integer id) { |
| | |
| | | byId.setUseCount(appCouponClient.getUseCountByCouponId(id).getData()); |
| | | return AjaxResult.ok(byId); |
| | | } |
| | | |
| | | |
| | | |
| | | @PostMapping("/exchangeRecord") |
| | | @ApiOperation(tags = {"管理后台-优惠券管理"},value = "优惠券查看详情-兑换记录") |
| | | public AjaxResult<PageInfo<ExchangeRecordVO>> exchangeRecord(@RequestBody ExchangeRecordGoodsQuery dto) { |
| | |
| | | } |
| | | return AjaxResult.ok(data); |
| | | } |
| | | |
| | | |
| | | |
| | | @ApiOperation(tags = {"管理后台-优惠券管理"},value = "发放优惠券") |
| | | @GetMapping(value = "/grantCoupon") |
| | | public AjaxResult grantCoupon(@RequestBody GrantCouponDto dto) { |
| | |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | @ApiOperation(tags = {"管理后台-优惠券管理"},value = "优惠券列表分页查询") |
| | | @PostMapping(value = "/pageList") |
| | | public AjaxResult<PageInfo<TCoupon>> pageList(@RequestBody CouponQuery dto) { |
| | |
| | | return AjaxResult.ok(enterpriseUserApplicationService.save(dto)); |
| | | } |
| | | |
| | | |
| | | |
| | | @ApiOperation(tags = {"后台-申请表单-集团用户"},value = "集团用户列表") |
| | | @PostMapping(value = "/page") |
| | | public AjaxResult<Boolean> page(@RequestBody TEnterpriseUserApplication dto) { |
| | |
| | | private TGoodsService goodsService; |
| | | @Autowired |
| | | private TActivityService activityService; |
| | | |
| | | |
| | | |
| | | |
| | | @PostMapping("/saveGoods") |
| | | @ApiOperation(tags = {"管理后台-商品管理"},value = "商品添加") |
| | | public AjaxResult saveActivity(@RequestBody TGoods dto) { |
| | | goodsService.save(dto); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/delete") |
| | | @ApiOperation(tags = {"管理后台-商品管理"},value = "商品删除") |
| | | public AjaxResult delete(Integer id) { |
| | | goodsService.removeById(id); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | @PostMapping("/updateVip") |
| | | @ApiOperation(tags = {"管理后台-商品管理"},value = "商品修改") |
| | | public AjaxResult updateActivity(@RequestBody TGoods dto) { |
| | | goodsService.updateById(dto); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/getInfo") |
| | | @ApiOperation(tags = {"管理后台-商品管理"},value = "商品查看详情") |
| | | public AjaxResult<TGoods> getInfo(Integer id) { |
| | | return AjaxResult.ok(goodsService.getById(id)); |
| | | } |
| | | |
| | | |
| | | |
| | | @ApiOperation(tags = {"管理后台-商品管理"},value = "商品列表分页查询") |
| | | @PostMapping(value = "/pageList") |
| | | public AjaxResult<PageInfo<TGoods>> pageList(@RequestBody GoodsDTO dto) { |
| | |
| | | public class THtmlController { |
| | | @Resource |
| | | private THtmlService htmlService; |
| | | |
| | | |
| | | |
| | | @ApiOperation(tags = {"后台-内容设置-协议服务"},value = "新增修改") |
| | | @PostMapping(value = "/saveOrUpdate") |
| | | public AjaxResult saveOrUpdate(@RequestBody THtml tHtml) { |
| | |
| | | } |
| | | |
| | | @ApiOperation(tags = {"后台-内容设置-协议服务"},value = "查询") |
| | | @PostMapping(value = "/selectByType/{type}") |
| | | @GetMapping(value = "/selectByType/{type}") |
| | | public AjaxResult selectByType(@PathVariable Integer type) { |
| | | THtml one = htmlService.lambdaQuery().eq(THtml::getType, type).last("limit 1").one(); |
| | | return AjaxResult.success(one); |
| | |
| | | } |
| | | return R.ok(g.getContent()); |
| | | } |
| | | |
| | | |
| | | |
| | | @GetMapping("/saveInfo") |
| | | @ApiOperation(tags = {"管理后台-积分管理"},value = "保存积分说明") |
| | | @ApiImplicitParams({ |
| | |
| | | package com.ruoyi.other.controller; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import com.ruoyi.other.api.domain.TInvoiceType; |
| | |
| | | @ResponseBody |
| | | @DeleteMapping("/delInvoiceType") |
| | | @ApiOperation(value = "删除发票类型", tags = {"管理后台-发票类型管理"}) |
| | | public AjaxResult<TInvoiceType> delInvoiceType(@RequestParam("id") Integer[] id){ |
| | | public AjaxResult<TInvoiceType> delInvoiceType(Integer[] id){ |
| | | List<TInvoiceType> tInvoiceTypes = invoiceTypeService.listByIds(Arrays.asList(id)); |
| | | for (TInvoiceType invoiceType : tInvoiceTypes) { |
| | | invoiceTypeService.removeById(invoiceType); |
| | | } |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | |
| | | |
| | | @ResponseBody |
| | | @DeleteMapping("/getInvoiceTypeList") |
| | | @ApiOperation(value = "获取开票类型", tags = {"小程序-充电发票"}) |
| | | public AjaxResult<List<TInvoiceType>> getInvoiceTypeList(){ |
| | | List<TInvoiceType> list = invoiceTypeService.list(new LambdaQueryWrapper<TInvoiceType>() |
| | | .eq(TInvoiceType::getDelFlag, 0).orderByAsc(TInvoiceType::getCreateTime)); |
| | | return AjaxResult.success(list); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据id获取发票类型 |
| | | * @param id |
| | | * @return |
| | | */ |
| | | @ResponseBody |
| | | @PostMapping("/getInvoiceType/{id}") |
| | | public R<TInvoiceType> getInvoiceType(@PathVariable Integer id){ |
| | | TInvoiceType invoiceType = invoiceTypeService.getById(id); |
| | | return R.ok(invoiceType); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | @ApiOperation(tags = {"后台-内容设置-公告管理"},value = "删除") |
| | | @PostMapping(value = "/deleteById/{id}") |
| | | public AjaxResult deleteById(@PathVariable Integer id) { |
| | | noticeService.removeById(id); |
| | | @DeleteMapping(value = "/deleteById") |
| | | public AjaxResult deleteById(String ids) { |
| | | String[] split = ids.split(","); |
| | | for (String id : split) { |
| | | noticeService.removeById(id); |
| | | } |
| | | |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @ApiOperation(tags = {"后台-内容设置-公告管理"},value = "查询") |
| | | @PostMapping(value = "/pageList") |
| | | public AjaxResult<Page<TNotice>> authPageList(@RequestBody NoticeQueryDto query) { |
| | | if (query.getStatus()==null){ |
| | | |
| | | return AjaxResult.success(noticeService.lambdaQuery() |
| | | .like(query.getContent()!=null&&query.getContent()!="",TNotice::getContent,query.getContent()) |
| | | .page(Page.of(query.getPageCurr(),query.getPageSize()))); |
| | | |
| | | } |
| | | |
| | | if (query.getStatus()==0){ |
| | | return AjaxResult.success(noticeService.lambdaQuery() |
| | | .le(TNotice::getStartTime, LocalDateTime.now()) |
| | |
| | | */ |
| | | @ApiOperation(tags = {"小程序-系统设置","后台-内容设置"},value = "联系客服,查询设置") |
| | | @GetMapping(value = "/getDetailById") |
| | | public AjaxResult<TSystemConfiguration> getDetailById(@RequestParam(name = "type")@ApiParam(value = "1=客服信息,2=系统设置") Integer type) { |
| | | public AjaxResult<TSystemConfiguration> getDetailById(@RequestParam("type")@ApiParam(value = "1=客服信息,2=系统设置") Integer type) { |
| | | return AjaxResult.ok(systemConfigurationService.getOne(Wrappers.lambdaQuery(TSystemConfiguration.class) |
| | | .eq(TSystemConfiguration::getType, type))); |
| | | } |
| | | |
| | | |
| | | |
| | | @ApiOperation(tags = {"后台-内容设置"},value = "客户信息,系统内容设置") |
| | | @GetMapping(value = "/save") |
| | | @PostMapping(value = "/save") |
| | | public AjaxResult getDetailById(@RequestBody TSystemConfiguration systemConfiguration) { |
| | | systemConfigurationService.saveOrUpdate(systemConfiguration); |
| | | return AjaxResult.success(); |
| | |
| | | import com.ruoyi.account.api.dto.SendCouponDto; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | | import com.ruoyi.common.core.web.page.BasePage; |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import com.ruoyi.other.api.domain.TCoupon; |
| | | import com.ruoyi.other.api.domain.TIntegralRule; |
| | |
| | | public R<TVip> getInfo1(@RequestParam("id")Integer id) { |
| | | return R.ok(vipService.getById(id)); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | @ApiOperation(tags = {"管理后台-会员管理"},value = "会员列表分页查询") |
| | | @PostMapping(value = "/pageList") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", required = true), |
| | | @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量",required = true) |
| | | }) |
| | | public AjaxResult<PageInfo<TVip>> pageList(Integer pageCurr,Integer pageSize) { |
| | | return AjaxResult.ok(vipService.pageList(pageCurr,pageSize)); |
| | | public AjaxResult<PageInfo<TVip>> pageList(@RequestBody BasePage basePage) { |
| | | return AjaxResult.ok(vipService.pageList(basePage.getPageCurr(), basePage.getPageSize())); |
| | | } |
| | | |
| | | @ApiOperation(tags = {"会员下拉框"},value = "会员列表分页查询") |
| | | @PostMapping(value = "/select") |
| | | @ApiImplicitParams({ |
| | | @ApiImplicitParam(name = "pageCurr", value = "分页参数,当前页码", required = true), |
| | | @ApiImplicitParam(name = "pageSize", value = "分页参数,每页数量",required = true) |
| | | }) |
| | | @GetMapping(value = "/select") |
| | | public AjaxResult<List<TVip>> select() { |
| | | return AjaxResult.ok(vipService.list()); |
| | | } |
| | |
| | | enabled: true |
| | | application-id: ${spring.application.name} |
| | | tx-service-group: seata_tx_group #此处配置自定义的seata事务分组名称 |
| | | enable-auto-data-source-proxy: true #关闭数据库代理 |
| | | enable-auto-data-source-proxy: false #关闭数据库代理 |
| | | service: |
| | | vgroup-mapping: |
| | | seata_tx_group: default |
| | |
| | | <id column="id" property="id" /> |
| | | <result column="name" property="name" /> |
| | | <result column="standard_condition" property="standardCondition" /> |
| | | <result column="condition" property="condition" /> |
| | | <result column="conditions" property="conditions" /> |
| | | <result column="create_time" property="createTime" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | id, name, standard_condition, condition, create_time, del_flag |
| | | id, name, standard_condition, conditions, create_time, del_flag |
| | | </sql> |
| | | |
| | | </mapper> |