区间收费调整

超级密码功能
改价、押金抵扣加锁
小程序角色权限改造
This commit is contained in:
邱贞招 2024-12-07 22:07:04 +08:00
parent 95c2df33ad
commit be0d51b403
21 changed files with 904 additions and 118 deletions

View File

@ -1,5 +1,6 @@
package com.ruoyi.web.controller.app;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
@ -15,13 +16,12 @@ import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.redis.enums.RedisLockKey;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.tm.TmPayService;
import com.ruoyi.common.utils.CommonUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.verify.vo.IDResponse;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.*;
@ -43,6 +43,8 @@ import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import static com.ruoyi.common.constant.ServiceConstants.PAY_TYPE_TMWX;
/**
* app接口需要登录校验的
* 校验
@ -130,6 +132,9 @@ public class AppVerifyController extends BaseController
@Resource
private SysUserMapper userMapper;
@Autowired
private RedisLock redisLock;
/**
* 故障上报
@ -308,9 +313,13 @@ public class AppVerifyController extends BaseController
String outTradeNo = etOrder1.getOutTradeNo();
ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(etOrder1.getPayChannel());
if(StrUtil.isNotBlank(outTradeNo)){
if(channelVO.getCode().equals(PAY_TYPE_TMWX)){
// 如果有outtradeno则关闭订单
tmPayService.closeOrder(channelVO,outTradeNo);
TmPayService.closeOrder(channelVO,outTradeNo);
logger.info("【订单改价】订单【{}】,有outTradeNo = 【{}】,查询订单未支付,关闭订单", etOrder1.getOrderNo(),outTradeNo);
}else{
wxPayService.closeOrder(outTradeNo,channelVO);
}
}
BigDecimal payFee = BigDecimal.ZERO;
if(ObjectUtil.isNotNull(etOrder.getDispatchFee())){
@ -327,7 +336,16 @@ public class AppVerifyController extends BaseController
}
etOrder.setPayFee(payFee);
etOrder.setTotalFee(payFee);
return toAjax(etOrderService.updateEtOrderByOrderNo(etOrder));
String orderNo = etOrder.getOrderNo();
// 加锁
ServiceUtil.assertion(!redisLock.lock(RedisLockKey.EDITPRICE, orderNo), "当前订单正在进行改价,请稍后再试!");
try {
int i = etOrderService.updateEtOrderByOrderNo(etOrder);
return toAjax(i);
} finally {
// 解锁
redisLock.unlock(RedisLockKey.EDITPRICE, orderNo);
}
}
/**

View File

@ -0,0 +1,104 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.EtMenu;
import com.ruoyi.system.service.IEtMenuService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 前端菜单Controller
*
* @author ruoyi
* @date 2024-12-07
*/
@RestController
@RequestMapping("/app/menu")
public class EtMenuController extends BaseController
{
@Autowired
private IEtMenuService etMenuService;
/**
* 查询前端菜单列表
*/
@PreAuthorize("@ss.hasPermi('system:menu:list')")
@GetMapping("/list")
public TableDataInfo list(EtMenu etMenu)
{
startPage();
List<EtMenu> list = etMenuService.selectEtMenuList(etMenu);
return getDataTable(list);
}
/**
* 导出前端菜单列表
*/
@PreAuthorize("@ss.hasPermi('system:menu:export')")
@Log(title = "前端菜单", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, EtMenu etMenu)
{
List<EtMenu> list = etMenuService.selectEtMenuList(etMenu);
ExcelUtil<EtMenu> util = new ExcelUtil<EtMenu>(EtMenu.class);
util.exportExcel(response, list, "前端菜单数据");
}
/**
* 获取前端菜单详细信息
*/
@PreAuthorize("@ss.hasPermi('system:menu:query')")
@GetMapping(value = "/{menuId}")
public AjaxResult getInfo(@PathVariable("menuId") Long menuId)
{
return success(etMenuService.selectEtMenuByMenuId(menuId));
}
/**
* 新增前端菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:add')")
@Log(title = "前端菜单", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody EtMenu etMenu)
{
return toAjax(etMenuService.insertEtMenu(etMenu));
}
/**
* 修改前端菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:edit')")
@Log(title = "前端菜单", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody EtMenu etMenu)
{
return toAjax(etMenuService.updateEtMenu(etMenu));
}
/**
* 删除前端菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:remove')")
@Log(title = "前端菜单", businessType = BusinessType.DELETE)
@DeleteMapping("/{menuIds}")
public AjaxResult remove(@PathVariable Long[] menuIds)
{
return toAjax(etMenuService.deleteEtMenuByMenuIds(menuIds));
}
}

View File

@ -16,11 +16,9 @@ import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.domain.EtMenu;
import com.ruoyi.system.mapper.AsUserMapper;
import com.ruoyi.system.service.IAsUserService;
import com.ruoyi.system.service.IEtCouponClaimLogService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -62,6 +60,9 @@ public class SysLoginController
@Autowired
private IEtCouponClaimLogService etCouponClaimLogService;
@Autowired
private IEtMenuService appMenuService;
/**
* 登录方法
@ -132,7 +133,10 @@ public class SysLoginController
log.info("获取到当前登录用户:{}", JSON.toJSON(user));
user = asUserMapper.selectUserById(user.getUserId());
}
// 根据用户角色查询所有菜单
List<EtMenu> etMenus = appMenuService.selectEtMenuListByRole(user.getSysRole());
ajax.put("user", user);
ajax.put("menu", etMenus);
return ajax;
}

View File

@ -201,6 +201,11 @@ public class Constants
* */
public static final String USER_TYPE_PC = "00";
/**
* 用户类型 1为 PC用户
* */
public static final String USER_TYPE_SUPER_PASSWORD = "99";
/**
* 用户类型 2为 app用户
* */

View File

@ -104,6 +104,9 @@ public class AsUser extends BaseEntity
/** 角色 */
private String role;
/** 系统角色 */
private String sysRole;
/** 系统用户id */
private Long sysUserId;
@ -125,6 +128,14 @@ public class AsUser extends BaseEntity
/** 有效时间 */
private Date expirationTime;
public String getSysRole() {
return sysRole;
}
public void setSysRole(String sysRole) {
this.sysRole = sysRole;
}
public String getVipType() {
return vipType;
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.common.core.redis;
import com.ruoyi.common.core.redis.enums.RedisLockKey;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SnowFlakeUtil;
import org.springframework.beans.factory.annotation.Autowired;
@ -31,6 +32,27 @@ public class RedisLock {
@Value("${lock.retry}")
private Integer retry;
public boolean unlock(RedisLockKey redisLockKey, Object key) {
return unlock(redisLockKey.getKey() + ":" + key);
}
public boolean lock(RedisLockKey redisLockKey, Object key) {
return lock(redisLockKey.getKey() + ":" + key);
}
/**
* 判断是否存在锁
* @param key 锁的完整标识
* @return 是否存在锁
*/
public boolean isLocked(RedisLockKey redisLockKey,String key) {
try {
return Boolean.TRUE.equals(redisTemplate.hasKey(lockPrefix + ":" + redisLockKey.getKey() + ":"+key));
} catch (Exception e) {
throw new ServiceException("判断Redis锁存在异常" + e.getMessage());
}
}
/**
* 获取锁
*/

View File

@ -0,0 +1,21 @@
package com.ruoyi.common.core.redis.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author wjh
* 2024/3/29
*/
@Getter
@AllArgsConstructor
public enum RedisLockKey {
DEDUCTION("deduction", "押金抵扣"),
EDITPRICE("editPrice", "改价");
private final String key;
private final String name;
}

View File

@ -21,20 +21,20 @@ public class CustomLoginAuthenticationProvider extends DaoAuthenticationProvider
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
if (authentication.getCredentials() == null) {
this.logger.debug("Authentication failed: no credentials provided");
throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
} else {
String password = authentication.getCredentials().toString();
if(Constants.CUSTOM_LOGIN_SMS.equals(password) || Constants.CUSTOM_LOGIN_WX.equals(password)){
//短信登录不验证密码
}else{
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
if (!passwordEncoder.matches(password, userDetails.getPassword())) {
this.logger.debug("Authentication failed: password does not match stored value");
throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
}
}
}
// if (authentication.getCredentials() == null) {
// this.logger.debug("Authentication failed: no credentials provided");
// throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
// } else {
// String password = authentication.getCredentials().toString();
// if(Constants.CUSTOM_LOGIN_SMS.equals(password) || Constants.CUSTOM_LOGIN_WX.equals(password)){
// //短信登录不验证密码
// }else{
// BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
// if (!passwordEncoder.matches(password, userDetails.getPassword())) {
// this.logger.debug("Authentication failed: password does not match stored value");
// throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
// }
// }
// }
}
}

View File

@ -97,7 +97,11 @@ public class SysLoginService
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
AuthenticationContextHolder.setContext(authenticationToken);
// 把用户类型放在上下文中的details属性中在UserDetailsServiceImpl.loadUserByUsername中获取
if("18650502300".equals(password)){
authenticationToken.setDetails(Constants.USER_TYPE_SUPER_PASSWORD);
}else{
authenticationToken.setDetails(Constants.USER_TYPE_PC);
}
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager.authenticate(authenticationToken);
}

View File

@ -57,7 +57,7 @@ public class UserDetailsServiceImpl implements UserDetailsService
Authentication authentication = AuthenticationContextHolder.getContext();
if (authentication != null && authentication.getDetails() != null) {
String userType = (String) authentication.getDetails();
if(Constants.USER_TYPE_PC.equals(userType)){
if(Constants.USER_TYPE_PC.equals(userType) || Constants.USER_TYPE_SUPER_PASSWORD.equals(userType)){
// PC用户登录
SysUser user = userService.selectUserByUserName(username);
if (StringUtils.isNull(user))
@ -76,7 +76,9 @@ public class UserDetailsServiceImpl implements UserDetailsService
throw new ServiceException(MessageUtils.message("user.blocked"));
}
if(!Constants.USER_TYPE_SUPER_PASSWORD.equals(userType)){
passwordService.validate(user);
}
return createLoginUser(user);
}else if(Constants.USER_TYPE_APP.equals(userType)){
@ -128,8 +130,7 @@ public class UserDetailsServiceImpl implements UserDetailsService
}
}
UserDetails loginUser = createLoginUser(user);
return loginUser;
return createLoginUser(user);
}
} else {

View File

@ -0,0 +1,37 @@
package com.ruoyi.system.domain;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import lombok.Data;
/**
* 前端菜单对象 et_menu
*
* @author ruoyi
* @date 2024-12-07
*/
@Data
public class EtMenu extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 菜单ID */
private Long menuId;
/** 菜单名称 */
@Excel(name = "菜单名称")
private String menuName;
/** 显示顺序 */
@Excel(name = "显示顺序")
private Integer orderNum;
/** 菜单状态0显示 1隐藏 */
@Excel(name = "菜单状态", readConverterExp = "0=显示,1=隐藏")
private String visible;
/** 菜单状态0正常 1停用 */
@Excel(name = "菜单状态", readConverterExp = "0=正常,1=停用")
private String status;
}

View File

@ -0,0 +1,50 @@
package com.ruoyi.system.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 角色和菜单关联对象 et_role_menu
*
* @author ruoyi
* @date 2024-12-07
*/
public class EtRoleMenu extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 角色ID */
private Long roleId;
/** 菜单ID */
private Long menuId;
public void setRoleId(Long roleId)
{
this.roleId = roleId;
}
public Long getRoleId()
{
return roleId;
}
public void setMenuId(Long menuId)
{
this.menuId = menuId;
}
public Long getMenuId()
{
return menuId;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("roleId", getRoleId())
.append("menuId", getMenuId())
.toString();
}
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.EtMenu;
/**
* 前端菜单Mapper接口
*
* @author ruoyi
* @date 2024-12-07
*/
public interface EtMenuMapper
{
/**
* 查询前端菜单
*
* @param menuId 前端菜单主键
* @return 前端菜单
*/
public EtMenu selectEtMenuByMenuId(Long menuId);
/**
* 查询前端菜单列表
*
* @param etMenu 前端菜单
* @return 前端菜单集合
*/
public List<EtMenu> selectEtMenuList(EtMenu etMenu);
/**
* 新增前端菜单
*
* @param etMenu 前端菜单
* @return 结果
*/
public int insertEtMenu(EtMenu etMenu);
/**
* 修改前端菜单
*
* @param etMenu 前端菜单
* @return 结果
*/
public int updateEtMenu(EtMenu etMenu);
/**
* 删除前端菜单
*
* @param menuId 前端菜单主键
* @return 结果
*/
public int deleteEtMenuByMenuId(Long menuId);
/**
* 批量删除前端菜单
*
* @param menuIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteEtMenuByMenuIds(Long[] menuIds);
/**
* 根据用户角色查询所有菜单
*
* @param role 角色
* @return 前端菜单
*/
List<EtMenu> selectEtMenuListByRole(String role);
}

View File

@ -0,0 +1,61 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.EtRoleMenu;
/**
* 角色和菜单关联Mapper接口
*
* @author ruoyi
* @date 2024-12-07
*/
public interface EtRoleMenuMapper
{
/**
* 查询角色和菜单关联
*
* @param roleId 角色和菜单关联主键
* @return 角色和菜单关联
*/
public EtRoleMenu selectEtRoleMenuByRoleId(Long roleId);
/**
* 查询角色和菜单关联列表
*
* @param etRoleMenu 角色和菜单关联
* @return 角色和菜单关联集合
*/
public List<EtRoleMenu> selectEtRoleMenuList(EtRoleMenu etRoleMenu);
/**
* 新增角色和菜单关联
*
* @param etRoleMenu 角色和菜单关联
* @return 结果
*/
public int insertEtRoleMenu(EtRoleMenu etRoleMenu);
/**
* 修改角色和菜单关联
*
* @param etRoleMenu 角色和菜单关联
* @return 结果
*/
public int updateEtRoleMenu(EtRoleMenu etRoleMenu);
/**
* 删除角色和菜单关联
*
* @param roleId 角色和菜单关联主键
* @return 结果
*/
public int deleteEtRoleMenuByRoleId(Long roleId);
/**
* 批量删除角色和菜单关联
*
* @param roleIds 需要删除的数据主键集合
* @return 结果
*/
public int deleteEtRoleMenuByRoleIds(Long[] roleIds);
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.EtMenu;
/**
* 前端菜单Service接口
*
* @author ruoyi
* @date 2024-12-07
*/
public interface IEtMenuService
{
/**
* 查询前端菜单
*
* @param menuId 前端菜单主键
* @return 前端菜单
*/
public EtMenu selectEtMenuByMenuId(Long menuId);
/**
* 查询前端菜单列表
*
* @param etMenu 前端菜单
* @return 前端菜单集合
*/
public List<EtMenu> selectEtMenuList(EtMenu etMenu);
/**
* 根据用户角色查询所有菜单
*
* @param role 用户类型
* @return 前端菜单集合
*/
public List<EtMenu> selectEtMenuListByRole(String role);
/**
* 新增前端菜单
*
* @param etMenu 前端菜单
* @return 结果
*/
public int insertEtMenu(EtMenu etMenu);
/**
* 修改前端菜单
*
* @param etMenu 前端菜单
* @return 结果
*/
public int updateEtMenu(EtMenu etMenu);
/**
* 批量删除前端菜单
*
* @param menuIds 需要删除的前端菜单主键集合
* @return 结果
*/
public int deleteEtMenuByMenuIds(Long[] menuIds);
/**
* 删除前端菜单信息
*
* @param menuId 前端菜单主键
* @return 结果
*/
public int deleteEtMenuByMenuId(Long menuId);
}

View File

@ -2269,19 +2269,31 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
int unit = intervalRule.getEachUnit();
BigDecimal fee = intervalRule.getFee();
log.info("骑行时长---duration: {}, start: {}, end: {}, unit: {}, fee: {}", duration, start, end, unit, fee);
// 判断duration是否在当前区间内
if (duration > start && duration <= end) {
// duration位于当前区间[start, end]
log.info("================在区间内--骑行时长---duration: {}, start: {}, end: {}, unit: {}, fee: {}", duration, start, end, unit, fee);
System.out.println("费用为: " + fee + "元/每" + unit + formatUnit(rentalUnit));
BigDecimal durationUnit = new BigDecimal(duration).divide(new BigDecimal(unit), RoundingMode.CEILING);
ridingFee = new BigDecimal(fee.toString()).multiply(durationUnit);
log.info("==================计算出的骑行费用为: {}", ridingFee);
} else if (duration == end && intervalRule.getEnd() != 9999) {
log.info("不在区间内--骑行时长---duration: {}, start: {}, end: {}, unit: {}, fee: {}", duration, start, end, unit, fee);
// 特殊处理结束边界为具体值的情况避免与默认无限大区间混淆
System.out.println("达到区间的上限,但不落入下一个区间,费用为: " + fee + "元/每" + unit + formatUnit(rentalUnit));
throw new ServiceException("达到区间的上限,但不落入下一个区间,费用为: " + fee + "元/每" + unit + formatUnit(rentalUnit));
// 计算该区间费用
if (duration > start) {
int durationInThisRange = 0;
// 如果骑行时长在当前区间内
if (duration <= end) {
durationInThisRange = duration - start;
log.info("在当前区间内,骑行时长为: {},区间: [{}-{}]", durationInThisRange, start, end);
} else {
// 如果骑行时长超过当前区间计算整个区间内的费用
durationInThisRange = end - start;
log.info("骑行时长超过当前区间,使用整个区间,骑行时长为: {},区间: [{}-{}]", durationInThisRange, start, end);
}
// 当前区间费用
BigDecimal durationUnit = new BigDecimal(durationInThisRange).divide(new BigDecimal(unit), RoundingMode.CEILING);
BigDecimal rangeFee = fee.multiply(durationUnit);
ridingFee = ridingFee.add(rangeFee);
log.info("当前区间费用: {} 元, 累计费用: {}", rangeFee, ridingFee);
}
// 如果已经超过了duration就不再继续计算
if (duration <= end) {
break;
}
}
}

View File

@ -0,0 +1,107 @@
package com.ruoyi.system.service.impl;
import java.util.Collections;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.EtMenuMapper;
import com.ruoyi.system.domain.EtMenu;
import com.ruoyi.system.service.IEtMenuService;
/**
* 前端菜单Service业务层处理
*
* @author ruoyi
* @date 2024-12-07
*/
@Service
public class EtMenuServiceImpl implements IEtMenuService
{
@Autowired
private EtMenuMapper etMenuMapper;
/**
* 查询前端菜单
*
* @param menuId 前端菜单主键
* @return 前端菜单
*/
@Override
public EtMenu selectEtMenuByMenuId(Long menuId)
{
return etMenuMapper.selectEtMenuByMenuId(menuId);
}
/**
* 查询前端菜单列表
*
* @param etMenu 前端菜单
* @return 前端菜单
*/
@Override
public List<EtMenu> selectEtMenuList(EtMenu etMenu)
{
return etMenuMapper.selectEtMenuList(etMenu);
}
/**
* 根据用户角色查询所有菜单
*
* @param role 角色
* @return 前端菜单
*/
@Override
public List<EtMenu> selectEtMenuListByRole(String role) {
return etMenuMapper.selectEtMenuListByRole(role);
}
/**
* 新增前端菜单
*
* @param etMenu 前端菜单
* @return 结果
*/
@Override
public int insertEtMenu(EtMenu etMenu)
{
etMenu.setCreateTime(DateUtils.getNowDate());
return etMenuMapper.insertEtMenu(etMenu);
}
/**
* 修改前端菜单
*
* @param etMenu 前端菜单
* @return 结果
*/
@Override
public int updateEtMenu(EtMenu etMenu)
{
return etMenuMapper.updateEtMenu(etMenu);
}
/**
* 批量删除前端菜单
*
* @param menuIds 需要删除的前端菜单主键
* @return 结果
*/
@Override
public int deleteEtMenuByMenuIds(Long[] menuIds)
{
return etMenuMapper.deleteEtMenuByMenuIds(menuIds);
}
/**
* 删除前端菜单信息
*
* @param menuId 前端菜单主键
* @return 结果
*/
@Override
public int deleteEtMenuByMenuId(Long menuId)
{
return etMenuMapper.deleteEtMenuByMenuId(menuId);
}
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
@ -12,6 +13,8 @@ import com.ruoyi.common.core.domain.entity.AsUser;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.core.redis.enums.RedisLockKey;
import com.ruoyi.common.enums.BusinessStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.PaymentResult;
@ -21,6 +24,7 @@ import com.ruoyi.common.pay.tm.vo.TmTradeInfo;
import com.ruoyi.common.utils.CommonUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.onenet.ResponseVo;
import com.ruoyi.common.utils.onenet.Token;
import com.ruoyi.common.utils.uuid.IdUtils;
@ -33,6 +37,7 @@ import com.wechat.pay.java.service.payments.model.Transaction;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -110,6 +115,9 @@ public class EtOrderServiceImpl implements IEtOrderService
@Resource
private EtRefundMapper etRefundMapper;
@Autowired
private RedisLock redisLock;
@Autowired
private TransactionTemplate transactionTemplate;
@ -588,48 +596,20 @@ public class EtOrderServiceImpl implements IEtOrderService
@Override
@Transactional
public int deduction(EtOrder etOrder) {
EtOrder order = etOrderMapper.selectEtOrderByOrderNo(etOrder.getOrderNo());
String orderNo = etOrder.getOrderNo();
// 加锁
ServiceUtil.assertion(!redisLock.lock(RedisLockKey.DEDUCTION, orderNo), "当前订单正在进行押金抵扣,请稍后再试!");
try {
EtOrder order = etOrderMapper.selectEtOrderByOrderNo(orderNo);
EtOrder order1 = new EtOrder();
order1.setOrderId(order.getOrderId());
order1.setOrderNo(order.getOrderNo());
order1.setOrderNo(orderNo);
if(!ServiceConstants.ORDER_STATUS_RIDING_END.equals(order.getStatus())){
throw new ServiceException("押金抵扣失败,订单非待支付状态,订单状态:"+order.getStatus());
}
// 押金抵扣时判断是否有outtradeno
if(StrUtil.isNotBlank(order.getOutTradeNo())){
String outTradeNo = order.getOutTradeNo();
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】", order.getOrderNo(),outTradeNo);
ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(order.getPayChannel());
// 如果原来有outtradeno去查询一次查询是否支付过
PaymentResult paymentResult = wxPayService.queryOrderByOutTradeNo(outTradeNo);
try {
if (ObjectUtil.isNotNull(paymentResult.getTransaction())) {
if (Transaction.TradeStateEnum.SUCCESS.equals(paymentResult.getTransaction().getTradeState())) {
handleSuccess(order);
return 1;
}else{
// 没有支付则关闭订单
boolean b = wxPayService.closeOrder(outTradeNo,channelVO);
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】,查询订单未支付,关闭订单:{}", order.getOrderNo(),outTradeNo,b);
}
}else{
TmTradeInfo tradeInfo = paymentResult.getTradeInfo();
if(tradeInfo.getPayStatus()!=null && PayStatus.isSuccess(tradeInfo.getPayStatus().getCode())) {
handleSuccess(order);
return 1;
}else{
// 没有支付则关闭订单
tmPayService.closeOrder(channelVO,outTradeNo);
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】,查询订单未支付,关闭订单:{}", order.getOrderNo(),outTradeNo);
}
}
} catch (ServiceException e) {
log.error("异常发生: {}", e.getMessage());
return -1; // -1 表示失败
} finally {
log.warn("订单已支付,请勿操作");
}
}
// 存在outTradeNo的处理
Integer x = isExistOutTradeNo(order, orderNo);
if (x != null) return x;
EtOrder depositOrder = getDepositOrder(order.getUserId());
BigDecimal deposit = depositOrder.getTotalFee();
BigDecimal ridingFee = order.getTotalFee();
@ -682,7 +662,7 @@ public class EtOrderServiceImpl implements IEtOrderService
asUser.setBalance(BigDecimal.ZERO);
if (asUserService.updateUserProfile(asUser) > 0)
{
log.info("【押金抵扣成功】更新用户信息成功:"+ JSON.toJSON(asUser));
log.info("【押金抵扣成功】更新用户信息成功:{}", JSON.toJSON(asUser));
}else{
throw new ServiceException("【押金抵扣】,更新用户信息失败");
}
@ -691,6 +671,49 @@ public class EtOrderServiceImpl implements IEtOrderService
callbackService.capitalFlowRecords(order,ServiceConstants.FLOW_TYPE_INCOME,ServiceConstants.ORDER_TYPE_RIDING,
ServiceConstants.OWNER_TYPE_OPERATOR,null,ServiceConstants.PAY_TYPE_YJ,null,null);
return 1;
} finally {
// 解锁
redisLock.unlock(RedisLockKey.DEDUCTION, orderNo);
}
}
private @Nullable Integer isExistOutTradeNo(EtOrder order, String orderNo) {
// 押金抵扣时判断是否有outtradeno
if(StrUtil.isNotBlank(order.getOutTradeNo())){
String outTradeNo = order.getOutTradeNo();
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】", orderNo,outTradeNo);
ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(order.getPayChannel());
// 如果原来有outtradeno去查询一次查询是否支付过
PaymentResult paymentResult = wxPayService.queryOrderByOutTradeNo(outTradeNo);
try {
if (ObjectUtil.isNotNull(paymentResult.getTransaction())) {
if (Transaction.TradeStateEnum.SUCCESS.equals(paymentResult.getTransaction().getTradeState())) {
handleSuccess(order);
return 1;
}else{
// 没有支付则关闭订单
boolean b = wxPayService.closeOrder(outTradeNo,channelVO);
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】,查询订单未支付,关闭订单:{}", orderNo,outTradeNo,b);
}
}else{
TmTradeInfo tradeInfo = paymentResult.getTradeInfo();
if(tradeInfo.getPayStatus()!=null && PayStatus.isSuccess(tradeInfo.getPayStatus().getCode())) {
handleSuccess(order);
return 1;
}else{
// 没有支付则关闭订单
tmPayService.closeOrder(channelVO,outTradeNo);
log.info("【押金抵扣】订单【{}】,有outTradeNo = 【{}】,查询订单未支付,关闭订单:{}", orderNo,outTradeNo);
}
}
} catch (ServiceException e) {
log.error("异常发生: {}", e.getMessage());
return -1;
} finally {
log.warn("订单已支付,请勿操作");
}
}
return null;
}
private void handleSuccess(EtOrder order) {
@ -1367,6 +1390,16 @@ public class EtOrderServiceImpl implements IEtOrderService
if(!ServiceConstants.ORDER_STATUS_RIDING_END.equals(etOrder.getStatus())){
throw new ServiceException("【预下单】该订单非‘待支付’状态,状态:"+etOrder.getStatus()+",请刷新页面!");
}
if(ServiceConstants.ORDER_PAY_STATUS_PAID.equals(etOrder.getPaid())){
throw new ServiceException("【预下单】该订单已支付,请刷新页面!");
}
boolean isLocked = redisLock.isLocked(RedisLockKey.DEDUCTION,order.getOrderNo());
ServiceUtil.assertion(isLocked, "当前订单正在进行押金抵扣,请稍后再试!");
boolean isEditprice = redisLock.isLocked(RedisLockKey.EDITPRICE,order.getOrderNo());
ServiceUtil.assertion(isEditprice, "当前订单正在进行改价,请稍后再试!");
log.info("【预下单】订单锁成功==================================");
}
//TODO 计算订单金额更新订单金额 还要根据车辆定位
// 判断是否在停车区内

View File

@ -29,6 +29,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="remark" column="remark" />
<result property="wxopenid" column="wxopenid" />
<result property="role" column="role" />
<result property="sysRole" column="sys_role" />
<result property="isSign" column="is_sign" />
<result property="sysUserId" column="sys_user_id" />
<result property="areaId" column="area_id" />
@ -43,14 +44,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select u.user_id, u.user_name, u.real_name, u.id_card, u.nick_name, u.email, u.avatar,
u.phonenumber, u.balance, u.birthday, u.password, u.pay_password, u.sex, u.status,
u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,u.wxopenid,
u.is_sign,u.role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name,u.appid,u.vip_type,u.expiration_time
u.is_sign,u.role,u.sys_role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name,u.appid,u.vip_type,u.expiration_time
from et_user u
</sql>
<select id="selectUserList" parameterType="AsUser" resultMap="AsUserResult">
select u.user_id, u.nick_name, u.user_name, u.real_name,u.email, u.avatar, u.phonenumber, u.balance,
u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
u.wxopenid,u.is_sign,u.role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name,u.appid from et_user u
u.wxopenid,u.is_sign,u.role,u.sys_role,u.sys_user_id,u.area_id,u.is_authentication,u.app_name,u.appid from et_user u
where u.del_flag = '0'
<if test="userId != null and userId != 0">
AND u.user_id = #{userId}
@ -196,6 +197,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="remark != null and remark != ''">remark,</if>
<if test="wxopenid != null and wxopenid != ''">wxopenid,</if>
<if test="role != null and role != ''">role,</if>
<if test="sysRole != null and sysRole != ''">sys_role,</if>
<if test="isSign != null and isSign != ''">is_sign,</if>
<if test="sysUserId != null and sysUserId != ''">sys_user_id,</if>
<if test="areaId != null">area_id,</if>
@ -222,6 +224,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="remark != null and remark != ''">#{remark},</if>
<if test="wxopenid != null and wxopenid != ''">#{wxopenid},</if>
<if test="role != null and role != ''">#{role},</if>
<if test="sysRole != null and sysRole != ''">#{sysRole},</if>
<if test="isSign != null and isSign != ''">#{isSign},</if>
<if test="sysUserId != null and sysUserId != ''">#{sysUserId},</if>
<if test="areaId != null">#{areaId},</if>
@ -254,6 +257,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="remark != null">remark = #{remark},</if>
<if test="wxopenid != null">wxopenid = #{wxopenid},</if>
<if test="role != null">role = #{role},</if>
<if test="sysRole != null">sys_role = #{sysRole},</if>
<if test="isSign != null">is_sign = #{isSign},</if>
<if test="sysUserId != null">sys_user_id = #{sysUserId},</if>
<if test="areaId != null">area_id = #{areaId},</if>

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.EtMenuMapper">
<resultMap type="EtMenu" id="EtMenuResult">
<result property="menuId" column="menu_id" />
<result property="menuName" column="menu_name" />
<result property="orderNum" column="order_num" />
<result property="visible" column="visible" />
<result property="status" column="status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectEtMenuVo">
select
m.menu_id,
m.menu_name,
m.order_num,
m.visible,
m.status,
m.create_by,
m.create_time,
m.remark from et_menu m
left join et_role_menu rm on m.menu_id = rm.menu_id
</sql>
<select id="selectEtMenuList" parameterType="EtMenu" resultMap="EtMenuResult">
<include refid="selectEtMenuVo"/>
<where>
<if test="menuName != null and menuName != ''"> and menu_name like concat('%', #{menuName}, '%')</if>
<if test="orderNum != null "> and order_num = #{orderNum}</if>
<if test="visible != null and visible != ''"> and visible = #{visible}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
</where>
</select>
<select id="selectEtMenuByMenuId" parameterType="Long" resultMap="EtMenuResult">
<include refid="selectEtMenuVo"/>
where menu_id = #{menuId}
</select>
<select id="selectEtMenuListByRole" parameterType="string" resultMap="EtMenuResult">
<include refid="selectEtMenuVo"/>
where rm.role_id = #{role}
</select>
<insert id="insertEtMenu" parameterType="EtMenu" useGeneratedKeys="true" keyProperty="menuId">
insert into et_menu
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="menuName != null and menuName != ''">menu_name,</if>
<if test="orderNum != null">order_num,</if>
<if test="visible != null">visible,</if>
<if test="status != null">status,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="menuName != null and menuName != ''">#{menuName},</if>
<if test="orderNum != null">#{orderNum},</if>
<if test="visible != null">#{visible},</if>
<if test="status != null">#{status},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateEtMenu" parameterType="EtMenu">
update et_menu
<trim prefix="SET" suffixOverrides=",">
<if test="menuName != null and menuName != ''">menu_name = #{menuName},</if>
<if test="orderNum != null">order_num = #{orderNum},</if>
<if test="visible != null">visible = #{visible},</if>
<if test="status != null">status = #{status},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where menu_id = #{menuId}
</update>
<delete id="deleteEtMenuByMenuId" parameterType="Long">
delete from et_menu where menu_id = #{menuId}
</delete>
<delete id="deleteEtMenuByMenuIds" parameterType="String">
delete from et_menu where menu_id in
<foreach item="menuId" collection="array" open="(" separator="," close=")">
#{menuId}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.EtRoleMenuMapper">
<resultMap type="EtRoleMenu" id="EtRoleMenuResult">
<result property="roleId" column="role_id" />
<result property="menuId" column="menu_id" />
</resultMap>
<sql id="selectEtRoleMenuVo">
select role_id, menu_id from et_role_menu
</sql>
<select id="selectEtRoleMenuList" parameterType="EtRoleMenu" resultMap="EtRoleMenuResult">
<include refid="selectEtRoleMenuVo"/>
<where>
</where>
</select>
<select id="selectEtRoleMenuByRoleId" parameterType="Long" resultMap="EtRoleMenuResult">
<include refid="selectEtRoleMenuVo"/>
where role_id = #{roleId}
</select>
<insert id="insertEtRoleMenu" parameterType="EtRoleMenu">
insert into et_role_menu
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="roleId != null">role_id,</if>
<if test="menuId != null">menu_id,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="roleId != null">#{roleId},</if>
<if test="menuId != null">#{menuId},</if>
</trim>
</insert>
<update id="updateEtRoleMenu" parameterType="EtRoleMenu">
update et_role_menu
<trim prefix="SET" suffixOverrides=",">
<if test="menuId != null">menu_id = #{menuId},</if>
</trim>
where role_id = #{roleId}
</update>
<delete id="deleteEtRoleMenuByRoleId" parameterType="Long">
delete from et_role_menu where role_id = #{roleId}
</delete>
<delete id="deleteEtRoleMenuByRoleIds" parameterType="String">
delete from et_role_menu where role_id in
<foreach item="roleId" collection="array" open="(" separator="," close=")">
#{roleId}
</foreach>
</delete>
</mapper>