新增区域bug修复

This commit is contained in:
SjS 2025-05-18 10:35:40 +08:00
parent 8174f55648
commit e0c8100eee
19 changed files with 157 additions and 91 deletions

View File

@ -44,4 +44,13 @@ public class UserVO extends User {
@ApiModelProperty("爆灯次数")
private Integer lightingNum;
@ApiModelProperty("所属商户账号")
private String mchName;
@ApiModelProperty("所属商户昵称")
private String mchNickName;
@ApiModelProperty("所属商户ID")
private String mchId;
}

View File

@ -41,6 +41,10 @@ public class RedisLock {
return lock(redisLockKey.getKey() + ":" + key);
}
public boolean lock(RedisLockKey redisLockKey, Object key, long seconds) {
return lock(redisLockKey.getKey() + ":" + key, String.valueOf(SnowFlakeUtil.newId()), seconds, TimeUnit.SECONDS, retry);
}
/**
* 获取锁
*/

View File

@ -15,6 +15,7 @@ public enum RedisLockKey {
ORDER_CREATE("order_create", "订单创建"),
PAY_CREATE("create_pay", "创建支付"),
ADD_DEVICE("add_device", "创建设备"),
BOOTH_LIGHTING("booth_lighting", "卡座爆灯"),
BOOTH_CHANGE_USER("booth_change_user", "用户换绑卡座"),
BOOTH_BIND_USER("booth_bind_user", "用户绑定卡座");

View File

@ -9,7 +9,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="ownerIds" column="owner_ids" typeHandler="com.ruoyi.common.mybatis.typehandler.LongSplitListTypeHandler"/>
</resultMap>
<!--TODO 处理用户列表管理关系-->
<sql id="selectAppVo">
select
ba.id,
@ -21,6 +20,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from bst_app ba
</sql>
<sql id="searchTabele">
bst_app ba
left join bst_user_app bua on ba.id = bua.app_id
left join sys_user su on bua.user_id = su.user_id
</sql>
<sql id="searchCondition">
<if test="query.id != null "> and ba.id = #{query.id}</if>
<if test="query.name != null and query.name != ''"> and ba.name like concat('%', #{query.name}, '%')</if>
@ -31,6 +36,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{item}
</foreach>
</if>
<if test="query.userIdList != null and query.userIdList.size() > 0">
and su.user_id in
<foreach item="item" collection="query.userIdList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
${@com.ruoyi.framework.util.DataScopeUtil@create(query.scope)
.appAlias("ba.id")
.build()

View File

@ -8,10 +8,14 @@ import lombok.Data;
public class BindRecordVO extends BindRecord{
@Excel(name = "用户名称")
@ApiModelProperty("用户名称")
@Excel(name = "用户账号")
@ApiModelProperty("用户账号")
private String userName;
@Excel(name = "用户昵称")
@ApiModelProperty("用户昵称")
private String nickName;
@Excel(name = "设备名称")
@ApiModelProperty("设备名称")
private String deviceName;

View File

@ -20,7 +20,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bbr.create_time,
bbr.type,
bd.device_name,
su.user_name
su.user_name,
su.nick_name
from bst_bind_record bbr
left join bst_device bd on bbr.device_id = bd.device_id
left join sys_user su on bbr.user_id = su.user_id

View File

@ -35,6 +35,7 @@ import com.ruoyi.iot.constants.IotConstants;
import com.ruoyi.iot.domain.response.CommandResponse;
import com.ruoyi.iot.service.IotService;
import com.ruoyi.iot.util.IotUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.bst.booth.mapper.BoothMapper;
@ -50,9 +51,9 @@ import org.springframework.transaction.support.TransactionTemplate;
* @author ruoyi
* @date 2025-04-18
*/
@Slf4j
@Service
public class BoothServiceImpl implements BoothService
{
public class BoothServiceImpl implements BoothService {
@Autowired
private BoothMapper boothMapper;
@Autowired
@ -87,8 +88,7 @@ public class BoothServiceImpl implements BoothService
* @return 卡座
*/
@Override
public BoothVO selectBoothByBoothId(Long id, boolean scope)
{
public BoothVO selectBoothByBoothId(Long id, boolean scope) {
if (id == null) {
return null;
}
@ -100,8 +100,7 @@ public class BoothServiceImpl implements BoothService
}
@Override
public BoothVO selectBoothByBoothNo(String boothNo, boolean scope)
{
public BoothVO selectBoothByBoothNo(String boothNo, boolean scope) {
if (boothNo == null) {
return null;
}
@ -119,6 +118,7 @@ public class BoothServiceImpl implements BoothService
List<BoothVO> list = this.selectBoothList(query);
return CollectionUtils.firstElement(list);
}
/**
* 查询卡座列表
*
@ -126,8 +126,7 @@ public class BoothServiceImpl implements BoothService
* @return 卡座
*/
@Override
public List<BoothVO> selectBoothList(BoothQuery booth)
{
public List<BoothVO> selectBoothList(BoothQuery booth) {
return boothMapper.selectBoothList(booth);
}
@ -138,8 +137,7 @@ public class BoothServiceImpl implements BoothService
* @return 结果
*/
@Override
public int insertBooth(Booth booth)
{
public int insertBooth(Booth booth) {
booth.setCreateTime(DateUtils.getNowDate());
Integer result = transactionTemplate.execute(status -> {
int rows = boothMapper.insertBooth(booth);
@ -159,8 +157,7 @@ public class BoothServiceImpl implements BoothService
* @return 结果
*/
@Override
public int updateBooth(Booth booth)
{
public int updateBooth(Booth booth) {
if (booth.getBoothNo() != null) {
boothValidator.validate(booth.getBoothId(), booth.getBoothNo());
}
@ -174,8 +171,7 @@ public class BoothServiceImpl implements BoothService
* @return 结果
*/
@Override
public int deleteBoothByBoothIds(List<Long> boothIds)
{
public int deleteBoothByBoothIds(List<Long> boothIds) {
return boothMapper.deleteBoothByBoothIds(boothIds);
}
@ -186,8 +182,7 @@ public class BoothServiceImpl implements BoothService
* @return 结果
*/
@Override
public int deleteBoothByBoothId(Long boothId)
{
public int deleteBoothByBoothId(Long boothId) {
return boothMapper.deleteBoothByBoothId(boothId);
}
@ -200,7 +195,9 @@ public class BoothServiceImpl implements BoothService
query.setUserId(userId);
query.setTime(LocalDateTime.now());
List<BoothVO> list = boothMapper.selectBoothList(query);
ServiceUtil.assertion(list != null && !list.isEmpty(),"请勿绑定多个卡座");
if (list != null && !list.isEmpty()){
return CollectionUtils.firstElement(list);
};
BoothVO booth = boothMapper.selectBoothByBoothNo(boothNo);
ServiceUtil.assertion(booth == null, "当前卡座不存在");
if (booth.getUserId() != null && booth.getExpiredTime() != null && booth.getExpiredTime().isAfter(LocalDateTime.now())) {
@ -270,7 +267,6 @@ public class BoothServiceImpl implements BoothService
}
@Override
public DeviceIotVO lighting(BoothVO booth, Long userId, boolean requiredIot) {
@ -283,7 +279,6 @@ public class BoothServiceImpl implements BoothService
ServiceUtil.assertion(vo == null, "请先购买余额");
ServiceUtil.assertion(vo.getNumber() <= 0, "余额不足,请充值");
// 设备相关校验
// 根据id查询出卡座对应的所有设备
DeviceQuery deviceQuery = new DeviceQuery();
deviceQuery.setBoothId(booth.getBoothId());
@ -291,23 +286,20 @@ public class BoothServiceImpl implements BoothService
deviceQuery.setBoothNo(booth.getBoothNo());
List<DeviceVO> deviceVOList = deviceMapper.selectDeviceList(deviceQuery);
//
// 设备相关校验
if (deviceVOList != null && !deviceVOList.isEmpty()) {
deviceVOList.forEach(deviceVO -> {
ServiceUtil.assertion(deviceVO == null || deviceVO.getDeviceId() == null, "设备不存在");
ServiceUtil.assertion(StringUtils.isAllBlank(deviceVO.getMac(), deviceVO.getMac2()), "设备MAC号为空");
ServiceUtil.assertion(deviceVO.getDuration() == null, "设备编号为%s的设备暂未设置开启时长", deviceVO.getDeviceNo());
if (deviceVO.getExpireTime()!=null) {
ServiceUtil.assertion( deviceVO.getExpireTime().isAfter(LocalDateTime.now()),"请勿在爆灯时间内重复爆灯");
}
});
}
// 新建IotVO 返回数据库操作与物联网操作结果
DeviceIotVO iotVO = new DeviceIotVO();
// 爆灯
Integer result = transactionTemplate.execute(status -> {
// 先扣减次数
LightingNum data = new LightingNum();
data.setNumber(1);
@ -334,7 +326,7 @@ public class BoothServiceImpl implements BoothService
ServiceUtil.assertion(i != 1, "操作失败");
deviceVOList.forEach(deviceVO -> {
boolean iotOp = this.lighting(deviceVO);
ServiceUtil.assertion(requiredIot && !iotOp, "");
ServiceUtil.assertion(requiredIot && !iotOp, "设备开启失败");
iotVO.setIot(iotOp);
});
return i;
@ -345,15 +337,16 @@ public class BoothServiceImpl implements BoothService
@Override
public boolean lighting(DeviceVO device) {
Integer result = transactionTemplate.execute(status -> {
device.setExpireTime(LocalDateTime.now().plusSeconds(device.getDuration()));
int i = deviceService.updateDevice(device);
ServiceUtil.assertion(i != 1,"更新设备防重复爆灯时间失败");
// 增加缓存 防止重复爆灯
boolean lock = redisLock.lock(RedisLockKey.BOOTH_LIGHTING, device.getDeviceNo(), device.getDuration() + 3);
if (lock) {
CommandResponse res = iotService.setTime(device, device.getDuration(), "爆灯");
// TODO: 要不要下面这个语句
ServiceUtil.assertion(res == null, "设备爆灯失败:未知错误");
boolean iot = IotUtil.isSuccess(res);
return iot? 1:0;
});
return MathUtils.equals(result,1);
return IotUtil.isSuccess(res);
} else {
ServiceUtil.assertion(true, "爆灯频繁,请稍等后再进行爆灯");
}
return false;
}
}

View File

@ -100,9 +100,9 @@ public class DeviceServiceImpl implements DeviceService
return null;
}
DeviceQuery query = new DeviceQuery();
query.setBoothId(id);
query.setDeviceId(id);
query.setScope(scope);
query.addStorePermission(StoreStaffPermission.BOOTH_VIEW.getCode());
query.addStorePermission(StoreStaffPermission.DEVICE_VIEW.getCode());
return this.selectOne(query);
}

View File

@ -11,8 +11,20 @@ public class LightingNumVO extends LightingNum{
@ApiModelProperty("店铺名")
private String storeName;
@Excel(name = "用户")
@ApiModelProperty("用户")
@Excel(name = "用户账号")
@ApiModelProperty("用户账号")
private String userName;
@Excel(name = "用户昵称")
@ApiModelProperty("用户昵称")
private String nickName;
@Excel(name = "用户账号")
@ApiModelProperty("用户账号")
private String mchName;
@Excel(name = "用户昵称")
@ApiModelProperty("用户昵称")
private String mchNickName;
}

View File

@ -21,7 +21,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bln.create_time,
bs.store_name,
bs.user_id as mch_id,
su.user_name
su.user_name,
su.nick_name
from <include refid="searchTables"/>
</sql>

View File

@ -86,6 +86,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="partName != null">part_name,</if>
<if test="picture != null">picture,</if>
<if test="createTime != null">create_time,</if>
<if test="orderNum != null">order_num,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="storeId != null">#{storeId},</if>
@ -93,6 +94,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="partName != null">#{partName},</if>
<if test="picture != null">#{picture},</if>
<if test="createTime != null">#{createTime},</if>
<if test="orderNum != null">#{orderNum},</if>
</trim>
</insert>

View File

@ -16,14 +16,12 @@ import com.ruoyi.bst.refund.service.RefundService;
import com.ruoyi.common.domain.vo.LocalDateDecimalVO;
import com.ruoyi.common.domain.vo.LongDecimalVO;
import com.ruoyi.common.pay.PayApi;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.SnowFlakeUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
@ -137,6 +135,8 @@ public class RefundServiceImpl implements RefundService
@Override
public int createRefund(Refund refund) {
Integer result = transactionTemplate.execute(status -> {
ServiceUtil.assertion(refund.getNumber()==0&&MathUtils.equals(refund.getAmount(),BigDecimal.ZERO),"退款金额和次数不能同时为0");
refund.setStatus(RefundStatus.REFUNDING.getStatus());
int insertRefund = this.insertRefund(refund);
ServiceUtil.assertion(insertRefund != 1, "创建退款订单失败");
@ -157,14 +157,13 @@ public class RefundServiceImpl implements RefundService
AppVO app = appService.selectAppById(vo.getAppId());
ServiceUtil.assertion(app == null, "ID为%s的APP不存在", vo.getAppId());
if (!MathUtils.equals(refund.getAmount(), BigDecimal.ZERO)){
// TODO 正式环境取消注释 调用API退款
payApi.refund(vo, channelConverter.toConfig(channel, app));
//TODO 5秒后支付成功测试正式环境需删除
// scheduledExecutorService.schedule(() -> {
// this.handleRefundSuccess(refund.getNo());
// }, 5, TimeUnit.SECONDS);
}
// TODO 正式环境取消注释 判断是否同步通知若是则直接处理支付成功
if (channelApiType.getIsRefundSync() != null && channelApiType.getIsRefundSync()) {
scheduledExecutorService.schedule(() -> {
@ -172,6 +171,11 @@ public class RefundServiceImpl implements RefundService
}, 10, TimeUnit.SECONDS);
}
//TODO 5秒后支付成功测试正式环境需删除
// scheduledExecutorService.schedule(() -> {
// this.handleRefundSuccess(refund.getNo());
// }, 5, TimeUnit.SECONDS);
return insertRefund;
});

View File

@ -28,8 +28,11 @@ public class StatKeys {
// 店铺数量
public static final String STORE_COUNT = "store_count";
// 用户爆灯次数
public static final String LIGHTING_NUM_COUNT = "lighting_num_count";
// 用户剩余爆灯次数
public static final String CURRENT_LIGHTING_NUM_COUNT = "current_lighting_num_count";
// 用户爆灯过的次数
public static final String USED_LIGHTING_NUM_COUNT = "user_lighting_num_count";
// 用户充值金额
public static final String USER_RECHARGE_AMOUNT = "user_recharge_amount";
// 用户退款金额

View File

@ -73,8 +73,12 @@ public class DashboardService {
if (keys.contains(StatKeys.DEVICE_ONLINE_STATUS_COUNT)) {
vo.setDeviceOnlineStatusMap(deviceDashboard.selectOnlineStatusCount(query.toDeviceQuery()));
}
// 爆灯次数
if (keys.contains(StatKeys.LIGHTING_NUM_COUNT)) {
// 当前爆灯次数
if (keys.contains(StatKeys.CURRENT_LIGHTING_NUM_COUNT)) {
vo.setUserLightingNum(lightingNumDashboard.selectCount(query.toLightingNumQuery()));
}
// 爆灯过的次数
if (keys.contains(StatKeys.CURRENT_LIGHTING_NUM_COUNT)) {
vo.setUserLightingNum(lightingNumDashboard.selectCount(query.toLightingNumQuery()));
}
// 用户充值金额

View File

@ -56,4 +56,7 @@ public class UserQuery extends UserVO {
@ApiModelProperty("创建日期范围")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private List<LocalDate> createDateRange;
@ApiModelProperty("所属店铺ID")
private Long storeId;
}

View File

@ -71,13 +71,19 @@
d.dept_name,
d.order_num,
d.leader,
d.status as dept_status
d.status as dept_status,
mch.user_name as mch_name,
mch.nick_name as mch_nick_name,
mch.user_id as mch_id
<include refid="searchTables"/>
</sql>
<sql id="searchTables">
from sys_user u
left join sys_dept d on u.dept_id = d.dept_id
left join bst_order bo on u.user_id = bo.user_id
left join bst_store bs on bo.store_id = bs.store_id
left join sys_user mch on bs.user_id = mch.user_id
</sql>
@ -337,6 +343,7 @@
<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
<if test="userType != null and userType != ''">user_type = #{userType},</if>
<if test="email != null ">email = #{email},</if>
<if test="declaration != null ">declaration = #{declaration},</if>
<if test="phonenumber != null ">phonenumber = #{phonenumber},</if>
<if test="sex != null and sex != ''">sex = #{sex},</if>
<if test="avatar != null and avatar != ''">avatar = #{avatar},</if>

View File

@ -27,7 +27,7 @@ public interface UserAssembler {
void assembleLastConsumeTime(List<UserConsumeVO> list);
/**
* 拼接用户爆灯次数
* 拼接用户剩余爆灯次数
* @param list
*/
void assembleLightingNum(List<UserVO> list);

View File

@ -38,9 +38,15 @@ public class AppBoothController extends BaseController {
return error("卡座编号不能为空");
}
BoothVO booth = boothService.selectBoothByBoothNo(boothNo);
ServiceUtil.assertion(booth==null,"当前卡座信息不存在");
ServiceUtil.assertion(booth.getUserId()==null,"请先绑定该卡座后再进行操作");
ServiceUtil.assertion(!booth.getUserId().equals(getUserId()),"您无权操作当前卡座设备");
if (booth == null) {
return error("当前卡座信息不存在");
}
if (booth.getUserId()==null) {
return error("您无权操作当前卡座设备");
}
if (!booth.getUserId().equals(getUserId())){
return error("您无权操作当前卡座设备");
}
return success(boothService.lighting(booth,getUserId(),requiredIot));
}

View File

@ -67,6 +67,7 @@ public class SysProfileController extends BaseController
User currentUser = loginUser.getUser();
currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setDeclaration(user.getDeclaration());
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
{
return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");