设备调整80%、充值记录、抄表

This commit is contained in:
墨大叔 2024-05-07 18:01:55 +08:00
parent 5ee530e494
commit 060019c830
38 changed files with 397 additions and 464 deletions

View File

@ -33,6 +33,9 @@ public class BillCountVo {
@ApiModelProperty("时间(小时)")
private Integer createHour; // 时间小时
@ApiModelProperty("店铺id")
private Long storeId;
@ApiModelProperty("充值金额(收入)")
private BigDecimal recharge; // 充值金额

View File

@ -73,11 +73,6 @@ public class SmDevice extends BaseEntity
@Past(message = "激活时间必须是过去的某个时间", groups = {ValidGroup.Create.class, ValidGroup.Update.class, ValidGroup.FrontUpdate.class})
private Date activationTime;
/** 剩余电量(度) */
@Excel(name = "剩余电量", readConverterExp = "度=")
@ApiModelProperty("剩余电量")
private BigDecimal surplusElectriQuantity;
@Excel(name = "总用电量")
@ApiModelProperty("总用电量KWH")
private BigDecimal totalElectriQuantity;
@ -111,22 +106,11 @@ public class SmDevice extends BaseEntity
@Min(value = 0, message = "电压不允许小于0", groups = {ValidGroup.Create.class, ValidGroup.Update.class, ValidGroup.FrontUpdate.class})
private BigDecimal voltage;
/** 所属商户ID */
@Excel(name = "所属商户ID")
@ApiModelProperty("所属商户ID")
@NotNull(message = "商户不允许为空", groups = {ValidGroup.Create.class, ValidGroup.Update.class})
private Long userId;
/** 用户昵称 */
@Excel(name = "用户昵称")
@ApiModelProperty("用户昵称")
private String nickName;
@Excel(name = "电费单价(元/度)")
@ApiModelProperty("电费单价(元/度)")
@Min(value = 0, message = "电费单价不允许小于0", groups = {ValidGroup.Create.class, ValidGroup.Update.class, ValidGroup.FrontUpdate.class})
private BigDecimal price;
@Excel(name = "欠费断电")
@ApiModelProperty("断电方式0欠费不断电1欠费立即断电")
@EnumValid(
@ -154,9 +138,6 @@ public class SmDevice extends BaseEntity
@ApiModelProperty("房租到期提醒方式")
private String noticeWay;
@ApiModelProperty("是否由用户承担服务费")
private Boolean tenantBearServiceFee;
@ApiModelProperty("上次拉取设备信息的时间")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastPullTime;

View File

@ -1,5 +1,6 @@
package com.ruoyi.ss.device.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
@ -8,6 +9,12 @@ import lombok.Data;
*/
@Data
public class SmDeviceCountVO {
@ApiModelProperty("店铺id")
private Long storeId;
@ApiModelProperty("商户id")
private Long userId;
@ApiModelProperty("数量")
private Integer count;
}

View File

@ -1,6 +1,8 @@
package com.ruoyi.ss.device.domain;
import com.ruoyi.common.valid.EnumValid;
import com.ruoyi.ss.device.domain.enums.DeviceGroupBy;
import com.ruoyi.ss.device.domain.enums.DeviceGroupByTable;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -13,15 +15,6 @@ import java.util.List;
@Data
public class SmDeviceQuery extends SmDevice {
@ApiModelProperty("租户id")
private Long tenantId;
@ApiModelProperty("是否默认设备")
private Boolean isDefault;
@ApiModelProperty("租户名称")
private String tenantName;
@ApiModelProperty("设备id列表")
private List<Long> deviceIds;
@ -45,12 +38,26 @@ public class SmDeviceQuery extends SmDevice {
@ApiModelProperty("分组字段")
@EnumValid(
clazz = SmDeviceQuery.class,
clazz = DeviceGroupBy.class,
method = "name",
message = "非法的分组字段"
)
private String groupBy;
@ApiModelProperty("分组表字段")
@EnumValid(
clazz = DeviceGroupByTable.class,
method = "name",
message = "非法的分组表字段"
)
private String groupByTable;
@ApiModelProperty("设备编号列表")
private List<String> deviceNos;
@ApiModelProperty("所属商户ID")
private Long userId;
@ApiModelProperty("商户id列表")
private List<Long> userIds;
}

View File

@ -6,5 +6,6 @@ package com.ruoyi.ss.device.domain.enums;
* 2024/4/30
*/
public enum DeviceGroupBy {
store_id, // 店铺id
store_id, // 店铺id
user_id, // 商户id
}

View File

@ -0,0 +1,12 @@
package com.ruoyi.ss.device.domain.enums;
/**
* @author wjh
* 2024/5/7
*/
public enum DeviceGroupByTable {
sd, // 设备表
ss // 店铺表
}

View File

@ -14,8 +14,8 @@ import java.util.Objects;
@Getter
public enum DeviceOutageWay {
NOT_OUTAGE("0", "欠费不断电"),
IMMEDIATE("1", "欠费立即断电");
NOT_OUTAGE("0", "到时不断电"),
IMMEDIATE("1", "到时立即断电");
private final String value;
private final String msg;

View File

@ -2,7 +2,9 @@ package com.ruoyi.ss.device.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonView;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.JsonViewProfile;
import com.ruoyi.common.core.domain.ValidGroup;
import com.ruoyi.ss.device.domain.DeviceView;
import com.ruoyi.ss.device.domain.SmDevice;
import com.ruoyi.ss.suit.domain.SuitVo;
@ -10,6 +12,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalTime;
import java.util.List;
@ -35,6 +38,7 @@ public class SmDeviceVo extends SmDevice {
private String userName;
@ApiModelProperty("图片")
@JsonView(JsonViewProfile.App.class)
private String picture;
@ApiModelProperty("型号标签列表")
@ -53,4 +57,7 @@ public class SmDeviceVo extends SmDevice {
@JsonView(JsonViewProfile.App.class)
@JsonFormat(pattern = "HH:mm", timezone = "GMT+8")
private LocalTime storeBusinessTimeEnd;
@ApiModelProperty("所属商户ID")
private Long userId;
}

View File

@ -89,18 +89,17 @@ public interface SmDeviceMapper
List<SmDeviceVo> selectSimpleList(SmDeviceQuery dto);
/**
* 设备绑定商户
* 设备绑定店铺
* @param deviceId 设备id
* @param userId 商户id
* @param storeId 店铺id
*/
int bindLandlord(@Param("deviceId") Long deviceId, @Param("userId") Long userId);
int bindStore(@Param("deviceId") Long deviceId, @Param("storeId") Long storeId);
/**
* 解绑商户
* @param deviceId 设备id
* @param userId 商户id
*/
int unbindLandlord(@Param("deviceId") Long deviceId, @Param("userId") Long userId);
int unbindStore(@Param("deviceId") Long deviceId);
/**
* 根据MAC查询设备

View File

@ -5,9 +5,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<mapper namespace="com.ruoyi.ss.device.mapper.SmDeviceMapper">
<resultMap type="SmDeviceVo" id="SmDeviceResult" autoMapping="true">
<result property="surplusElectriQuantity" column="surplus_electri_quantity" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="totalElectriQuantity" column="total_electri_quantity" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="price" column="price" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="initReading" column="init_reading" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="modelTags" column="model_tags" typeHandler="com.ruoyi.system.mapper.typehandler.StringSplitListTypeHandler" />
</resultMap>
@ -21,12 +19,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null and status != ''"> and sd.status = #{status}</if>
<if test="userName != null and userName != ''"> and sd.user_name like concat('%', #{userName}, '%')</if>
<if test="nickName != null and nickName != ''"> and sd.nick_name like concat('%', #{nickName}, '%')</if>
<if test="userId != null"> and sd.user_id = #{userId}</if>
<if test="userId != null"> and su.user_id = #{userId}</if>
<if test="storeId != null"> and sd.store_id = #{storeId}</if>
<if test="deviceId != null"> and sd.device_id = #{deviceId}</if>
<if test="tenantId != null"> and sdt.tenant_id = #{tenantId}</if>
<if test="isDefault != null"> and sdt.is_default = #{isDefault}</if>
<if test="tenantName != null">and su.nick_name like concat('%', #{tenantName}, '%')</if>
<if test="expireDay != null">and sd.expire_day = #{expireDay}</if>
<if test="deviceIds != null and deviceIds.size() > 0">
and sd.device_id in
@ -42,10 +37,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</if>
<if test="isBind != null">
<if test="isBind">
and sd.user_id is not null
and sd.store_id is not null
</if>
<if test="!isBind">
and sd.user_id is null
and sd.store_id is null
</if>
</if>
<if test="storeIds != null and storeIds.size() > 0">
@ -54,73 +49,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{item}
</foreach>
</if>
<if test="userIds != null and userIds.size() > 0">
and ss.user_id in
<foreach collection="userIds" open="(" close=")" separator="," item="item">
#{item}
</foreach>
</if>
<if test="deleted == null">and sd.deleted = false</if>
<if test="deleted != null">and sd.deleted = #{deleted}</if>
</sql>
<select id="selectTenantIds" resultType="java.lang.Long">
select sdt.tenant_id
from sm_device_tenant sdt
where sdt.device_id = #{deviceId}
</select>
<select id="selectTenantList" resultMap="com.ruoyi.ss.user.mapper.SmUserMapper.SmUserResult">
select su.user_name,
su.nick_name,
su.user_id
from sm_device_tenant sdt
left join sm_user su on sdt.tenant_id = su.user_id
where sdt.device_id = #{deviceId}
</select>
<select id="selectSmDeviceList" parameterType="SmDeviceQuery" resultMap="SmDeviceResult">
<sql id="selectVo">
select
<trim suffixOverrides=",">
sd.*,
sm.model_name model,
sm.picture picture,
sm.tags model_tags,
ss.name store_name,
landlord.user_name user_name,
<if test="tenantId != null">
sdt.is_default is_default,
</if>
</trim>
sm.model_name as model,
sm.picture as picture,
sm.tags as model_tags,
ss.name as store_name,
su.user_id as user_id,
su.user_name as user_name
from sm_device sd
<if test="tenantId != null">
left join sm_device_tenant sdt on sdt.device_id = sd.device_id
left join sm_user su on sdt.tenant_id = su.user_id
</if>
left join sm_user landlord on landlord.user_id = sd.user_id
left join sm_model sm on sm.model_id = sd.model_id
left join sm_store ss on ss.store_id = sd.store_id
left join sm_user su on su.user_id = ss.user_id
</sql>
<select id="selectSmDeviceList" parameterType="SmDeviceQuery" resultMap="SmDeviceResult">
<include refid="selectVo"/>
<where>
<include refid="searchCondition"/>
</where>
group by sd.device_id
order by sd.create_time desc
</select>
<sql id="selectOneVo">
select
sd.*,
sm.model_name model,
sm.tags model_tags,
ss.name store_name,
landlord.user_name user_name
from sm_device sd
left join sm_user landlord on landlord.user_id = sd.user_id
left join sm_model sm on sm.model_id = sd.model_id
left join sm_store ss on ss.store_id = sd.store_id
</sql>
<select id="selectSmDeviceByDeviceId" parameterType="Long" resultMap="SmDeviceResult">
<include refid="selectOneVo"/>
<include refid="selectVo"/>
where sd.device_id = #{deviceId} and sd.deleted = false
</select>
<select id="selectByDeviceNo" resultMap="SmDeviceResult">
<include refid="selectOneVo"/>
<include refid="selectVo"/>
where sd.device_no = #{deviceNo} and sd.deleted = false
</select>
@ -156,6 +124,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{item}
</foreach>
and sd.deleted = false
group by sd.store_id
</select>
<resultMap id="DeviceCount" type="SmDeviceCountVO" autoMapping="true">
@ -165,16 +134,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectCommonCount" resultMap="DeviceCount">
<trim prefix="select" suffixOverrides=",">
<if test="groupBy != null">
sd.${groupBy},
<if test="groupByTable == null">
sd.${groupBy},
</if>
<if test="groupByTable != null">
${groupByTable}.${groupBy},
</if>
</if>
count(sd.device_id) as `count`
</trim>
from sm_device sd
left join sm_store ss on ss.store_id = sd.store_id
<where>
<include refid="searchCondition"/>
</where>
<if test="groupBy != null">
group by sd.${groupBy}
<if test="groupByTable == null">
group by sd.${groupBy}
</if>
<if test="groupByTable != null">
group by ${groupByTable}.${groupBy}
</if>
</if>
</select>
@ -189,26 +169,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="modelId != null">model_id,</if>
<if test="mac != null">mac,</if>
<if test="activationTime != null">activation_time,</if>
<if test="surplusElectriQuantity != null">surplus_electri_quantity,</if>
<if test="totalElectriQuantity != null">total_electri_quantity,</if>
<if test="onlineStatus != null">online_status,</if>
<if test="status != null">status,</if>
<if test="realTimePower != null">real_time_power,</if>
<if test="electricity != null">electricity,</if>
<if test="voltage != null">voltage,</if>
<if test="userId != null">user_id,</if>
<if test="nickName != null and nickName != ''">nick_name,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
<if test="price != null">price,</if>
<if test="outageWay != null">outage_way,</if>
<if test="wifi != null">wifi,</if>
<if test="enableExpireNotice != null">enable_expire_notice,</if>
<if test="noticeWay != null">notice_way,</if>
<if test="tenantBearServiceFee != null">tenant_bear_service_fee,</if>
<if test="deleted != null">deleted,</if>
<if test="lastPullTime != null">last_pull_time,</if>
<if test="expireDay != null">expire_day,</if>
@ -222,26 +198,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="modelId != null">#{modelId},</if>
<if test="mac != null">#{mac},</if>
<if test="activationTime != null">#{activationTime},</if>
<if test="surplusElectriQuantity != null">#{surplusElectriQuantity},</if>
<if test="totalElectriQuantity != null">#{totalElectriQuantity},</if>
<if test="onlineStatus != null">#{onlineStatus},</if>
<if test="status != null">#{status},</if>
<if test="realTimePower != null">#{realTimePower},</if>
<if test="electricity != null">#{electricity},</if>
<if test="voltage != null">#{voltage},</if>
<if test="userId != null">#{userId},</if>
<if test="nickName != null and nickName != ''">#{nickName},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
<if test="price != null">#{price},</if>
<if test="outageWay != null">#{outageWay},</if>
<if test="wifi != null">#{wifi},</if>
<if test="enableExpireNotice != null">#{enableExpireNotice},</if>
<if test="noticeWay != null">#{noticeWay},</if>
<if test="tenantBearServiceFee != null">#{tenantBearServiceFee},</if>
<if test="deleted != null">#{deleted},</if>
<if test="lastPullTime != null">#{lastPullTime},</if>
<if test="expireDay != null">#{expireDay},</if>
@ -275,32 +247,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="modelId != null">model_id = #{modelId},</if>
<if test="mac != null">mac = #{mac},</if>
<if test="activationTime != null">activation_time = #{activationTime},</if>
<if test="surplusElectriQuantity != null">surplus_electri_quantity = #{surplusElectriQuantity},</if>
<if test="totalElectriQuantity != null">total_electri_quantity = #{totalElectriQuantity},</if>
<if test="onlineStatus != null">online_status = #{onlineStatus},</if>
<if test="status != null">`status` = #{status},</if>
<if test="realTimePower != null">real_time_power = #{realTimePower},</if>
<if test="electricity != null">electricity = #{electricity},</if>
<if test="voltage != null">voltage = #{voltage},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="price != null">price = #{price},</if>
<if test="outageWay != null">outage_way = #{outageWay},</if>
<if test="expireDate != null">expire_date = #{expireDate},</if>
<if test="wifi != null">wifi = #{wifi},</if>
<if test="enableExpireNotice != null">enable_expire_notice = #{enableExpireNotice},</if>
<if test="noticeWay != null">notice_way = #{noticeWay},</if>
<if test="tenantBearServiceFee != null">tenant_bear_service_fee = #{tenantBearServiceFee},</if>
<if test="deleted != null">deleted = #{deleted},</if>
<if test="lastPullTime != null">last_pull_time = #{lastPullTime},</if>
<if test="expireDay != null">expire_day = #{expireDay},</if>
<if test="initReading != null">init_reading = #{initReading},</if>
<if test="powerStatus != null">power_status = #{powerStatus},</if>
<if test="expireTime != null">expire_time = #{expireTime},</if>
</trim>
where device_id = #{deviceId}
</update>
@ -314,16 +283,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach>
</update>
<update id="bindLandlord">
<update id="bindStore">
update sm_device
set user_id = #{userId}
where device_id = #{deviceId} and user_id is null
set store_id = #{storeId}
where device_id = #{deviceId} and store_id is null
</update>
<update id="unbindLandlord">
<update id="unbindStore">
update sm_device
set user_id = null
where device_id = #{deviceId} and user_id = #{userId}
set user_id = null,
store_id = null
where device_id = #{deviceId}
</update>
<delete id="deleteSmDeviceByDeviceId" parameterType="Long">

View File

@ -19,12 +19,6 @@ public interface DeviceAssembler {
*/
void assembleTenant(List<SmDeviceVo> list);
/**
* 设置设备分组
* @param device
*/
void setStore(SmDevice device);
/**
* 拼接套餐列表
* @param list

View File

@ -53,20 +53,6 @@ public class DeviceAssemblerImpl implements DeviceAssembler {
}
device.setTenantIds(tenants.stream().map(SmDeviceTenant::getTenantId).collect(Collectors.toList()));
}
}
@Override
public void setStore(SmDevice device) {
// 商户的默认店铺
if (device.getUserId() != null && device.getStoreId() == null) {
StoreVo defaultStore = smDeviceGroupService.selectDefaultStore(device.getUserId());
if (defaultStore == null) {
// defaultStore = smDeviceGroupService.insertDefaultStore(device.getUserId());
ServiceUtil.assertion(defaultStore == null, "该用户没有默认店铺");
}
device.setStoreId(defaultStore.getStoreId());
}
}
/**

View File

@ -15,4 +15,10 @@ public interface DeviceValidator {
*/
boolean isExistNo(List<String> deviceNos);
/**
* 判断设备是否属于指定用户
* @param deviceId 设备id
* @param userId 用户id
*/
boolean isBelong(Long deviceId, Long userId);
}

View File

@ -79,32 +79,6 @@ public interface ISmDeviceService
*/
boolean addTime(Long deviceId, BigDecimal num);
/**
* 租户绑定设备
* @param deviceId 设备id
*/
boolean tenantBind(Long tenantId, Long deviceId);
/**
* 租户解绑设备
* @param userId 租户id
* @param deviceId 设备id
*/
boolean tenantUnbind(Long userId, Long deviceId);
/**
* 获取用户的默认设备
* @param userId 用户id
*/
public SmDeviceVo selectDefaultDevice(Long userId);
/**
* 设置用户默认设备
* @param tenantId 租户id
* @param deviceId 设备id
*/
boolean setDefaultDevice(Long tenantId, Long deviceId);
/**
* 逻辑删除
*/
@ -129,30 +103,20 @@ public interface ISmDeviceService
*/
void pullDeviceInfo(List<Long> deviceIds);
/**
* 通过设备id绑定设备
* 设备第一次绑定为商户
* 其他时候绑定为租户
* @param userId 用户id
* @param deviceId 设备id
*/
boolean bind(Long userId, Long deviceId);
/**
* 通过mac绑定设备
* 设备第一次绑定为商户
* 其他时候绑定为租户
* @param userId 用户id
* @param mac 设备mac
* @param storeId 店铺ID
* @param deviceNo 设备编号SN
*/
boolean bind(Long userId, String mac);
boolean bind(Long storeId, String deviceNo);
/**
* 商户解绑设备
* @param userId 用户id
* @param deviceId 设备id
*/
boolean landlordUnbind(Long userId, Long deviceId);
boolean unbindStore(Long deviceId);
/**
* 通过mac查询设备

View File

@ -18,6 +18,8 @@ import com.ruoyi.ss.deviceTenant.mapper.SmDeviceTenantMapper;
import com.ruoyi.ss.deviceTenant.service.ISmDeviceTenantService;
import com.ruoyi.ss.resetRecord.domain.SmResetRecord;
import com.ruoyi.ss.resetRecord.service.ISmResetRecordService;
import com.ruoyi.ss.store.domain.StoreVo;
import com.ruoyi.ss.store.service.IStoreService;
import com.ruoyi.ss.user.domain.SmUserVo;
import com.ruoyi.ss.user.mapper.SmUserMapper;
import com.ruoyi.iot.domain.IotDeviceInfo;
@ -27,6 +29,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
@ -79,6 +82,9 @@ public class SmDeviceServiceImpl implements ISmDeviceService
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private IStoreService storeService;
@Value("${debug}")
private Boolean debug;
@ -143,7 +149,6 @@ public class SmDeviceServiceImpl implements ISmDeviceService
device.setElectricity(deviceInfo.getA());
device.setVoltage(deviceInfo.getV());
device.setRealTimePower(deviceInfo.getP());
device.setSurplusElectriQuantity(deviceInfo.getM()); // 剩余电量
device.setTotalElectriQuantity(deviceInfo.getW()); // 电量
}
} else {
@ -162,9 +167,6 @@ public class SmDeviceServiceImpl implements ISmDeviceService
public int insertSmDevice(SmDevice data)
{
this.validate(data, false);
deviceAssembler.setStore(data); // 商户分组
data.setCreateTime(DateUtils.getNowDate());
data.setStatus(DeviceStatus.NORMAL.getStatus());
return smDeviceMapper.insertSmDevice(data);
@ -202,7 +204,7 @@ public class SmDeviceServiceImpl implements ISmDeviceService
LoginUser loginUser = SecurityUtils.getLoginUser();
if (update) {
ServiceUtil.assertion(smDevice.getDeviceId() == null, "参数错误设备id不允许为空");
SmDevice device = smDeviceMapper.selectSmDeviceByDeviceId(smDevice.getDeviceId());
SmDeviceVo device = smDeviceMapper.selectSmDeviceByDeviceId(smDevice.getDeviceId());
ServiceUtil.assertion(device == null || device.getDeleted(), "设备" + smDevice.getDeviceId() + "不存在");
if (LoginType.FRONT.equals(loginUser.getLoginType())) {
ServiceUtil.assertion(!Objects.equals(device.getUserId(), loginUser.getUserId()), "这不是您的设备");
@ -288,19 +290,22 @@ public class SmDeviceServiceImpl implements ISmDeviceService
}
@Override
@Transactional
@Transactional(propagation = Propagation.REQUIRES_NEW)
public boolean addTime(Long deviceId, BigDecimal num) {
ServiceUtil.assertion(num.compareTo(BigDecimal.ZERO) < 0, "增加的时长不允许小于0");
SmDeviceVo device = smDeviceMapper.selectSmDeviceByDeviceId(deviceId);
ServiceUtil.assertion(device == null, "设备不存在");
ServiceUtil.assertion(!StringUtils.hasText(device.getMac()), "设备MAC号为空");
ServiceUtil.assertion(DeviceStatus.FIXING.getStatus().equals(device.getStatus()), "设备正在维修中,无法使用");
// 更新数据库时长
int updateCount = smDeviceMapper.addTime(deviceId, num);
ServiceUtil.assertion(updateCount != 1, "增加时长失败,请刷新后重试");
// 修改状态为使用中
changeStatus(deviceId, DeviceStatus.USING);
// 物联网设备增加时长
boolean rechargeResult = iotService.recharge(device.getMac(), num);
ServiceUtil.assertion(!rechargeResult, "设备充值失败");
@ -311,53 +316,11 @@ public class SmDeviceServiceImpl implements ISmDeviceService
return true;
}
@Override
@Transactional
public boolean tenantBind(Long tenantId, Long deviceId) {
// 校验
ServiceUtil.assertion(tenantId == null || deviceId == null, "参数错误");
ServiceUtil.assertion(smDeviceTenantService.selectIsBind(tenantId, deviceId), "用户与该设备已经绑定,无需重复绑定");
SmDeviceVo device = smDeviceMapper.selectSmDeviceByDeviceId(deviceId);
ServiceUtil.assertion(device == null || device.getDeleted(), "待绑定的设备不存在");
ServiceUtil.assertion(device.getUserId() == null, "该设备还未绑定商户,请先绑定商户");
SmUserVo user = smUserMapper.selectSmUserByUserId(tenantId);
ServiceUtil.assertion(user == null, "用户不存在");
// 执行绑定
SmDeviceTenant deviceTenant = new SmDeviceTenant();
deviceTenant.setTenantId(tenantId);
deviceTenant.setDeviceId(deviceId);
int insertCount = smDeviceTenantService.insertSmDeviceTenant(deviceTenant);
ServiceUtil.assertion(insertCount != 1 , "绑定失败,请刷新后重试");
// 设置为默认设备
setDefaultDevice(tenantId, deviceId);
return true;
}
@Override
@Transactional
public boolean tenantUnbind(Long tenantId, Long deviceId) {
// 判断是否已绑定
ServiceUtil.assertion(!smDeviceTenantService.selectIsBind(tenantId, deviceId), "用户尚未绑定该设备,无法解绑");
// 执行解绑
int deleteCount = smDeviceTenantService.unBind(tenantId, deviceId);
ServiceUtil.assertion(deleteCount != 1, "设备解绑失败,请刷新后重试");
// 若解绑的设备为默认设备则设置新的默认设备
SmDeviceVo defaultDevice = selectDefaultDevice(tenantId);
if (defaultDevice == null) {
List<SmDeviceVo> deviceList = this.selectTenantDeviceList(tenantId);
if (!CollectionUtils.isEmpty(deviceList)) {
setDefaultDevice(tenantId, deviceList.get(0).getDeviceId());
}
}
return true;
private int changeStatus(Long deviceId, DeviceStatus status) {
SmDevice device = new SmDevice();
device.setDeviceId(deviceId);
device.setStatus(status.getStatus());
return smDeviceMapper.updateSmDevice(device);
}
/**
@ -370,7 +333,6 @@ public class SmDeviceServiceImpl implements ISmDeviceService
return Collections.emptyList();
}
SmDeviceQuery dto = new SmDeviceQuery();
dto.setTenantId(tenantId);
dto.setDeleted(false);
List<SmDeviceVo> list = smDeviceMapper.selectSmDeviceList(dto);
assembleDeviceInfo(list);
@ -380,39 +342,6 @@ public class SmDeviceServiceImpl implements ISmDeviceService
return list;
}
@Override
public SmDeviceVo selectDefaultDevice(Long tenantId) {
if (tenantId == null) {
return null;
}
SmDeviceQuery dto = new SmDeviceQuery();
dto.setTenantId(tenantId);
dto.setIsDefault(true);
dto.setDeleted(false);
List<SmDeviceVo> list = smDeviceMapper.selectSmDeviceList(dto);
assembleDeviceInfo(list);
if (CollectionUtils.isEmpty(list)) {
return null;
}
return list.get(0);
}
@Override
@Transactional
public boolean setDefaultDevice(Long tenantId, Long deviceId) {
SmDeviceVo device = smDeviceMapper.selectSmDeviceByDeviceId(deviceId);
ServiceUtil.assertion(device == null || device.getDeleted(), "设备不存在");
deviceAssembler.assembleTenant(Collections.singletonList(device));
ServiceUtil.assertion(!device.getTenantIds().contains(tenantId), "该用户不是这个设备的租户");
SmUserVo user = smUserMapper.selectSmUserByUserId(tenantId);
ServiceUtil.assertion(user == null, "用户不存在");
int updateCount = smDeviceTenantMapper.setDefault(tenantId, deviceId);
ServiceUtil.assertion(updateCount == 0, "设置默认设备失败");
return true;
}
@Override
public boolean logicDel(List<Long> deviceIds) {
this.validatePreLogicDelete(deviceIds);
@ -497,7 +426,6 @@ public class SmDeviceServiceImpl implements ISmDeviceService
SmDevice data = new SmDevice();
data.setDeviceId(device.getDeviceId());
if (deviceInfo != null) {
data.setSurplusElectriQuantity(deviceInfo.getM());
data.setLastPullTime(deviceInfo.getAt());
data.setTotalElectriQuantity(deviceInfo.getW());
data.setPowerStatus(deviceInfo.getS());
@ -529,37 +457,26 @@ public class SmDeviceServiceImpl implements ISmDeviceService
@Override
@Transactional
public boolean bind(Long userId, Long deviceId) {
ServiceUtil.assertion(userId == null || deviceId == null, "绑定设备参数错误");
SmDeviceVo device = smDeviceMapper.selectSmDeviceByDeviceId(deviceId);
ServiceUtil.assertion(device == null || device.getDeleted(), "设备不存在");
if (device.getUserId() == null) {
// 商户为空绑定商户
this.bindLandlord(userId, deviceId);
} else {
// 绑定租户
this.tenantBind(userId, deviceId);
}
return true;
}
@Override
@Transactional
public boolean bind(Long userId, String mac) {
public boolean bind(Long storeId, String deviceNo) {
// 判断设备是否存在
SmDeviceVo device = selectByMac(mac);
SmDeviceVo device = selectByDeviceNo(deviceNo);
ServiceUtil.assertion(device == null, "设备未录入");
ServiceUtil.assertion(device.getStoreId() != null, "该设备已被绑定");
// 不存在则新增
if (device == null || device.getDeleted()) {
device = new SmDeviceVo();
device.setMac(mac);
this.insertSmDevice(device);
}
// 查询店铺
StoreVo store = storeService.selectSmStoreById(storeId);
ServiceUtil.assertion(store == null, "店铺不存在");
// 绑定
return bind(userId, device.getDeviceId());
// 绑定店铺
int updateCount = smDeviceMapper.bindStore(device.getDeviceId(), storeId);
ServiceUtil.assertion(updateCount != 1, "当前设备信息已变更,请刷新后重试");
// 记录设备绑定
scheduledExecutorService.schedule(() -> {
smDeviceBindRecordService.record(store.getUserId(), device.getDeviceId());
}, 0, TimeUnit.SECONDS);
return true;
}
/**
@ -597,6 +514,7 @@ public class SmDeviceServiceImpl implements ISmDeviceService
SmDevice form = new SmDevice();
form.setDeviceId(deviceId);
form.setExpireTime(now);
form.setStatus(DeviceStatus.NORMAL.getStatus());
smDeviceMapper.updateSmDevice(form);
// TODO 物联网设备归零
@ -614,19 +532,6 @@ public class SmDeviceServiceImpl implements ISmDeviceService
return true;
}
/**
* 判断设备是否还有租户
* @param deviceId
* @return
*/
private boolean hasTenant(Long deviceId) {
if (deviceId == null) {
return false;
}
List<SmDeviceTenant> tenantList = smDeviceTenantService.selectByDeviceId(deviceId);
return !CollectionUtils.isEmpty(tenantList);
}
/**
* 设备是否已经被绑定
*
@ -639,7 +544,7 @@ public class SmDeviceServiceImpl implements ISmDeviceService
return false;
}
SmDeviceVo device = smDeviceMapper.selectSimpleSmDeviceByMac(mac);
return device != null && device.getUserId() != null;
return device != null && device.getStoreId() != null;
}
/**
@ -658,7 +563,7 @@ public class SmDeviceServiceImpl implements ISmDeviceService
}
/**
* 查询各店铺的设备数量,分组
* 查询各店铺的设备数量,店铺
*
* @param storeIds 店铺id
*/
@ -675,7 +580,7 @@ public class SmDeviceServiceImpl implements ISmDeviceService
}
/**
* 条件查询数量分组
* 条件查询数量店铺
*
* @param query 查询条件
* @param keyMapper 键值的映射
@ -731,8 +636,15 @@ public class SmDeviceServiceImpl implements ISmDeviceService
return 0;
}
try {
smDevice.setCreateTime(DateUtils.getNowDate());
return smDeviceMapper.insertSmDevice(smDevice);
Integer result = transactionTemplate.execute(status -> {
SmDeviceVo byMac = selectByMac(smDevice.getMac());
if (byMac == null) {
smDevice.setCreateTime(DateUtils.getNowDate());
return smDeviceMapper.insertSmDevice(smDevice);
}
return 0;
});
return result == null ? 0 : result;
} catch (Exception e) {
log.error("add init device error: {}", e.getMessage());
return 0;
@ -741,42 +653,16 @@ public class SmDeviceServiceImpl implements ISmDeviceService
@Override
@Transactional
public boolean landlordUnbind(Long userId, Long deviceId) {
public boolean unbindStore(Long deviceId) {
SmDeviceVo device = smDeviceMapper.selectSmDeviceByDeviceId(deviceId);
ServiceUtil.assertion(device == null || device.getDeleted(), "设备不存在");
ServiceUtil.assertion(!Objects.equals(device.getUserId(), userId), "您不是该设备的商户");
ServiceUtil.assertion(DeviceStatus.USING.getStatus().equals(device.getStatus()), "设备正在使用中,无法解除绑定");
deviceAssembler.assembleTenant(Collections.singletonList(device));
ServiceUtil.assertion(!CollectionUtils.isEmpty(device.getTenantIds()), "该设备还有租户绑定,无法解除绑定");
int updateCount = smDeviceMapper.unbindLandlord(deviceId, userId);
int updateCount = smDeviceMapper.unbindStore(deviceId);
ServiceUtil.assertion(updateCount != 1, "当前设备信息已变更,请刷新后重试");
return true;
}
// 绑定商户
@Transactional
public void bindLandlord(Long userId, Long deviceId) {
ServiceUtil.assertion(userId == null || deviceId == null, "商户绑定设备参数错误");
SmUserVo user = smUserMapper.selectSmUserByUserId(userId);
int updateCount = smDeviceMapper.bindLandlord(deviceId, userId);
ServiceUtil.assertion(updateCount != 1, "当前设备信息已变更,请刷新后重试");
// 更新设备分组
SmDevice device = new SmDevice();
device.setDeviceId(deviceId);
device.setUserId(userId);
deviceAssembler.setStore(device);
smDeviceMapper.updateSmDevice(device);
// 记录设备绑定
scheduledExecutorService.schedule(()-> {
smDeviceBindRecordService.record(userId, deviceId);
},0, TimeUnit.SECONDS);
}
/**
* 设备绑定SN码
*

View File

@ -14,6 +14,7 @@ import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
/**
* @author wjh
@ -39,4 +40,19 @@ public class DeviceValidatorImpl extends BaseValidator implements DeviceValidato
query.setDeviceNos(deviceNos);
return deviceService.selectCount(query) == new HashSet<>(deviceNos).size();
}
/**
* 判断设备是否属于指定用户
*
* @param deviceId 设备id
* @param userId 用户id
*/
@Override
public boolean isBelong(Long deviceId, Long userId) {
if (deviceId == null) {
return false;
}
SmDeviceVo device = deviceService.selectSmDeviceByDeviceId(deviceId);
return device != null && Objects.equals(device.getUserId(), userId);
}
}

View File

@ -28,10 +28,6 @@ public class SmMeterReadingRecord extends BaseEntity
@Excel(name = "用户id")
private Long userId;
/** 抄表时剩余电量 */
@Excel(name = "抄表时剩余电量")
private BigDecimal surplusElectriQuantity;
/** 抄表时总用电量 */
@Excel(name = "抄表时总用电量")
private BigDecimal totalElectriQuantity;

View File

@ -8,7 +8,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="recordId" column="record_id" />
<result property="deviceId" column="device_id" />
<result property="userId" column="user_id" />
<result property="surplusElectriQuantity" column="surplus_electri_quantity" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="totalElectriQuantity" column="total_electri_quantity" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="createTime" column="create_time" />
<result property="createDate" column="create_date" />
@ -24,7 +23,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
smrr.record_id,
smrr.device_id,
smrr.user_id,
smrr.surplus_electri_quantity,
smrr.total_electri_quantity,
smrr.create_time,
smrr.used_electri_quantity
@ -124,7 +122,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="recordId != null">record_id,</if>
<if test="deviceId != null">device_id,</if>
<if test="userId != null">user_id,</if>
<if test="surplusElectriQuantity != null">surplus_electri_quantity,</if>
<if test="totalElectriQuantity != null">total_electri_quantity,</if>
<if test="createTime != null">create_time,</if>
<if test="usedElectriQuantity != null">used_electri_quantity,</if>
@ -133,7 +130,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="recordId != null">#{recordId},</if>
<if test="deviceId != null">#{deviceId},</if>
<if test="userId != null">#{userId},</if>
<if test="surplusElectriQuantity != null">#{surplusElectriQuantity},</if>
<if test="totalElectriQuantity != null">#{totalElectriQuantity},</if>
<if test="createTime != null">#{createTime},</if>
<if test="usedElectriQuantity != null">#{usedElectriQuantity},</if>
@ -142,12 +138,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<insert id="batchInsert">
insert into sm_meter_reading_record(device_id, user_id, surplus_electri_quantity, total_electri_quantity, create_time, used_electri_quantity)
insert into sm_meter_reading_record(device_id, user_id, total_electri_quantity, create_time, used_electri_quantity)
<foreach collection="list" open="values" separator="," item="i">
<trim prefix="(" suffixOverrides="," suffix=")">
#{i.deviceId},
#{i.userId},
#{i.surplusElectriQuantity},
#{i.totalElectriQuantity},
#{i.createTime},
#{i.usedElectriQuantity},
@ -160,7 +155,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<trim prefix="SET" suffixOverrides=",">
<if test="deviceId != null">device_id = #{deviceId},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="surplusElectriQuantity != null">surplus_electri_quantity = #{surplusElectriQuantity},</if>
<if test="totalElectriQuantity != null">total_electri_quantity = #{totalElectriQuantity},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="usedElectriQuantity != null">used_electri_quantity = #{usedElectriQuantity},</if>

View File

@ -155,7 +155,6 @@ public class SmMeterReadingRecordServiceImpl implements ISmMeterReadingRecordSer
record.setDeviceId(device.getDeviceId());
record.setUserId(device.getUserId());
record.setTotalElectriQuantity(deviceInfo == null ? device.getTotalElectriQuantity() : deviceInfo.getW());
record.setSurplusElectriQuantity(deviceInfo == null ? device.getSurplusElectriQuantity() : deviceInfo.getM());
record.setCreateTime(now);
if (history == null || history.getTotalElectriQuantity() == null) {
record.setUsedElectriQuantity(deviceInfo == null ? device.getTotalElectriQuantity() : deviceInfo.getW());

View File

@ -114,4 +114,9 @@ public interface IStoreService
* 查询店铺映射表
*/
<K> Map<K, StoreVo> selectMap(StoreQuery query, Function<? super StoreVo, ? extends K> keyMapper);
/**
* ids查询列表
*/
List<StoreVo> selectSmStoreListByIds(List<Long> ids);
}

View File

@ -1,6 +1,8 @@
package com.ruoyi.ss.store.service.impl;
import com.ruoyi.common.utils.CollectionUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.ss.dashboard.BillCountVo;
import com.ruoyi.ss.device.domain.SmDeviceCountVO;
import com.ruoyi.ss.device.domain.SmDeviceQuery;
import com.ruoyi.ss.device.domain.enums.DeviceGroupBy;
@ -9,12 +11,20 @@ import com.ruoyi.ss.device.domain.enums.DeviceStatus;
import com.ruoyi.ss.device.service.ISmDeviceService;
import com.ruoyi.ss.store.domain.StoreVo;
import com.ruoyi.ss.store.service.StoreAssembler;
import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillGroupBy;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillType;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@ -27,6 +37,9 @@ public class StoreAssemblerImpl implements StoreAssembler {
@Autowired
private ISmDeviceService deviceService;
@Autowired
private TransactionBillService transactionBillService;
/**
* 拼接设备数量
*
@ -68,7 +81,7 @@ public class StoreAssemblerImpl implements StoreAssembler {
}
/**
* TODO 拼接本月收入
* 拼接本月收入
*
* @param list
*/
@ -77,13 +90,29 @@ public class StoreAssemblerImpl implements StoreAssembler {
if (CollectionUtils.isEmptyElement(list)) {
return;
}
TransactionBillQuery query = new TransactionBillQuery();
LocalDate now = LocalDate.now();
query.setGroupBy(TransactionBillGroupBy.store_id.name());
query.setStoreIds(list.stream().map(StoreVo::getStoreId).filter(Objects::nonNull).distinct().collect(Collectors.toList()));
query.setStatus(TransactionBillStatus.SUCCESS.getStatus());
query.setType(TransactionBillType.RECHARGE.getType());
query.setMonth(now.getMonthValue());
query.setYear(now.getYear());
Map<Long, BillCountVo> map = transactionBillService.selectCountMap(query, BillCountVo::getStoreId);
for (StoreVo store : list) {
store.setMonthIncome(BigDecimal.ZERO);
BillCountVo count = map.get(store.getStoreId());
if (count != null) {
store.setMonthIncome(count.getRecharge());
} else {
store.setMonthIncome(BigDecimal.ZERO);
}
}
}
/**
* TODO 拼接本日收入
* 拼接本日收入
*
* @param list
*/
@ -92,8 +121,22 @@ public class StoreAssemblerImpl implements StoreAssembler {
if (CollectionUtils.isEmptyElement(list)) {
return;
}
TransactionBillQuery query = new TransactionBillQuery();
query.setGroupBy(TransactionBillGroupBy.store_id.name());
query.setStoreIds(list.stream().map(StoreVo::getStoreId).filter(Objects::nonNull).distinct().collect(Collectors.toList()));
query.setStatus(TransactionBillStatus.SUCCESS.getStatus());
query.setType(TransactionBillType.RECHARGE.getType());
query.setCreateDate(DateUtils.getNowDate());
Map<Long, BillCountVo> map = transactionBillService.selectCountMap(query, BillCountVo::getStoreId);
for (StoreVo store : list) {
store.setTodayIncome(BigDecimal.ZERO);
BillCountVo count = map.get(store.getStoreId());
if (count != null) {
store.setTodayIncome(count.getRecharge());
} else {
store.setTodayIncome(BigDecimal.ZERO);
}
}
}
@ -107,8 +150,23 @@ public class StoreAssemblerImpl implements StoreAssembler {
if (CollectionUtils.isEmptyElement(list)) {
return;
}
TransactionBillQuery query = new TransactionBillQuery();
LocalDate lastMonth = LocalDate.now().plusMonths(-1);
query.setGroupBy(TransactionBillGroupBy.store_id.name());
query.setStoreIds(list.stream().map(StoreVo::getStoreId).filter(Objects::nonNull).distinct().collect(Collectors.toList()));
query.setStatus(TransactionBillStatus.SUCCESS.getStatus());
query.setType(TransactionBillType.RECHARGE.getType());
query.setMonth(lastMonth.getMonthValue());
query.setYear(lastMonth.getYear());
Map<Long, BillCountVo> map = transactionBillService.selectCountMap(query, BillCountVo::getStoreId);
for (StoreVo store : list) {
store.setLastMonthIncome(BigDecimal.ZERO);
BillCountVo count = map.get(store.getStoreId());
if (count != null) {
store.setLastMonthIncome(count.getRecharge());
} else {
store.setLastMonthIncome(BigDecimal.ZERO);
}
}
}

View File

@ -130,23 +130,10 @@ public class StoreServiceImpl implements IStoreService
@Override
public List<StoreVo> listCount(StoreQuery query) {
List<StoreVo> list = new ArrayList<>();
// 查询全部设备数据
SmDeviceQuery deviceDto = new SmDeviceQuery();
deviceDto.setUserId(query.getUserId());
int count = smDeviceService.selectCount(deviceDto);
StoreVo all = new StoreVo();
all.setDeviceCount(count);
all.setName("全部");
list.add(all);
// 查询各各店铺的设备数据
List<StoreVo> storeList = storeMapper.selectSmStoreList(query);
storeAssembler.assembleDeviceCount(storeList);
list.addAll(storeList);
return list;
return storeList;
}
@Override
@ -282,6 +269,21 @@ public class StoreServiceImpl implements IStoreService
return list.stream().collect(Collectors.toMap(keyMapper, item -> item));
}
/**
* ids查询列表
*
* @param ids
*/
@Override
public List<StoreVo> selectSmStoreListByIds(List<Long> ids) {
if (CollectionUtils.isEmptyElement(ids)) {
return Collections.emptyList();
}
StoreQuery query = new StoreQuery();
query.setStoreIds(ids);
return selectSmStoreList(query);
}
/**
* 通用查询数量
*

View File

@ -67,4 +67,7 @@ public class TransactionBillQuery extends TransactionBill {
@ApiModelProperty("状态列表")
private List<String> statusList;
@ApiModelProperty("店铺ID列表")
private List<Long> storeIds;
}

View File

@ -17,4 +17,5 @@ public enum TransactionBillGroupBy {
create_date,
create_hour,
create_year_month,
store_id
}

View File

@ -71,13 +71,6 @@ public interface TransactionBillMapper
*/
List<BillCountVo> selectCount(TransactionBillQuery dto);
/**
* 修改支付方式
* @param billId 订单id
* @param payType 支付方式
*/
int updatePayType(@Param("billId") Long billId, @Param("payType") Long payType, @Param("accountNo") String accountNo);
/**
* 充值成功
* @param billId 订单id

View File

@ -81,6 +81,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#{item}
</foreach>
</if>
<if test="storeIds != null and storeIds.size() > 0">
and stb.store_id in
<foreach item="item" collection="storeIds" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</sql>
<select id="selectSmTransactionBillList" parameterType="TransactionBillQuery" resultMap="SmTransactionBillResult">
@ -103,6 +109,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="createMonth" column="create_month"/>
<result property="createDay" column="create_day"/>
<result property="createYearMonth" column="create_year_month"/>
<result property="storeId" column="store_id"/>
<result property="serviceCharge" column="service_charge" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler"/>
<result property="channelCost" column="channel_cost" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler"/>
<result property="profit" column="profit" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler"/>
@ -128,6 +135,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="groupBy == 'create_year_month' or groupBy == 'create_date' or groupBy == 'create_month'">
DATE_FORMAT( stb.create_time, '%Y-%m' ) AS `create_year_month`,
</if>
<if test="groupBy == 'store_id'">
stb.store_id as store_id,
</if>
SUM(IF( stb.type = '1' and stb.status = '2', stb.arrival_amount, 0 )) AS recharge,
SUM(IF( stb.type = '2' and stb.status = '14', stb.arrival_amount, 0 )) AS withdraw,
SUM(stb.service_charge) AS service_charge,

View File

@ -10,7 +10,9 @@ import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
/**
* 充值记录Service接口
@ -82,13 +84,6 @@ public interface TransactionBillService
*/
String addOrder(TransactionBill body);
/**
* 更新支付方式
* @param billId 订单id
* @param transactionBillPayType 支付方式
*/
int updatePayType(Long billId, TransactionBillPayType transactionBillPayType, String accountNo);
/**
* 获取支付结果
* @param billNo
@ -205,4 +200,11 @@ public interface TransactionBillService
* @param timeUnit 时间单位
*/
void refreshPayResultBeforeExpire(String billNo, int delay, TimeUnit timeUnit);
/**
* 查询数量并映射
* @param query 查询条件
* @param keyMapper 映射方法
*/
<K> Map<K, BillCountVo> selectCountMap(TransactionBillQuery query, Function<? super BillCountVo, ? extends K> keyMapper);
}

View File

@ -37,6 +37,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.utils.CollectionUtils;
@ -45,6 +47,7 @@ import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -512,30 +515,29 @@ public class TransactionBillServiceImpl implements TransactionBillService {
ServiceUtil.assertion(TransactionBillDeviceRechargeStatus.SUCCESS.getStatus().equals(bill.getDeviceRechargeStatus()), "设备已充值成功,不允许再次充值");
}
// 开关时间增加,四舍五入,保留1位小数
deviceService.addTime(bill.getDeviceId(), bill.getSuitTime());
// 电表电量增加,四舍五入,保留1位小数
boolean success = false;
try {
success = deviceService.addTime(bill.getDeviceId(), bill.getSuitTime());
} catch (Exception e) {
this.handleDeviceRechargeFail(billId);
}
// 修改设备充值状态成功
transactionBillMapper.updateDeviceRechargeStatus(bill.getBillId(), TransactionBillDeviceRechargeStatus.SUCCESS.getStatus());
if (success) {
transactionBillMapper.updateDeviceRechargeStatus(bill.getBillId(), TransactionBillDeviceRechargeStatus.SUCCESS.getStatus());
}
return true;
}
/**
* 修改支付方式
* @param billId 订单id
* @param transactionBillPayType 支付方式
* @param accountNo 账号银行卡openId
* 处理设备充值失败
*/
@Override
@Transactional
public int updatePayType(Long billId, TransactionBillPayType transactionBillPayType, String accountNo) {
ServiceUtil.assertion( billId == null, "订单id不允许为空");
TransactionBill dbBill = transactionBillMapper.selectSmTransactionBillByBillId(billId);
ServiceUtil.assertion(dbBill == null, "订单不存在");
ServiceUtil.assertion(!TransactionBillStatus.UNPAID.getStatus().equals(dbBill.getStatus()), "只有未支付的订单可以更改支付方式");
return transactionBillMapper.updatePayType(billId, transactionBillPayType.getType(), accountNo);
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
public void handleDeviceRechargeFail(Long billId) {
// 修改设备充值状态为失败
transactionBillMapper.updateDeviceRechargeStatus(billId, TransactionBillDeviceRechargeStatus.FAIL.getStatus());
}
/**
@ -735,6 +737,21 @@ public class TransactionBillServiceImpl implements TransactionBillService {
}
}
/**
* 查询数量并映射
*
* @param query 查询条件
* @param keyMapper 映射方法
*/
@Override
public <K> Map<K, BillCountVo> selectCountMap(TransactionBillQuery query, Function<? super BillCountVo, ? extends K> keyMapper) {
List<BillCountVo> list = this.selectCount(query);
if (CollectionUtils.isEmptyElement(list)) {
return Collections.emptyMap();
}
return list.stream().collect(Collectors.toMap(keyMapper, item -> item));
}
// 关闭订单
private void closeOrder(String billNo) {
TransactionBill bill = transactionBillMapper.selectSmTransactionBillByBillNo(billNo);

View File

@ -25,7 +25,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
<result property="deviceCount" column="device_count" />
<result property="rechargeAmount" column="recharge_amount" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="withDrawlAmount" column="with_drawl_amount" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="wechat" column="wechat" />
@ -65,12 +64,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
su.wx_open_id,
su.delete_time,
su.is_mch,
count(sd.device_id) as device_count,
(select sum(stb.money) from sm_transaction_bill stb where stb.user_id = su.user_id and stb.type = '1' and stb.status = '2') as recharge_amount,
(select sum(stb.arrival_amount) from sm_transaction_bill stb where stb.user_id = su.user_id and stb.type = '2' and stb.status = '14') as with_drawl_amount,
(select sum(stb.arrival_amount) from sm_transaction_bill stb where stb.mch_id = su.user_id and stb.type = '1' and stb.status = '2') as total_income
from sm_user su
left join sm_device sd on sd.user_id = su.user_id
</sql>
<sql id="searchCondition">
@ -104,13 +101,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="searchCondition"/>
and su.del_flag = '0'
</where>
group by su.user_id
</select>
<select id="selectSmUserByUserId" parameterType="Long" resultMap="SmUserResult">
<include refid="selectSmUserVo"/>
where su.user_id = #{userId} and su.del_flag = '0'
group by su.user_id
</select>
<select id="selectCount" resultType="java.lang.Integer">
@ -124,7 +119,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectSmUserByWxOpenId" resultMap="SmUserResult">
<include refid="selectSmUserVo"/>
where su.wx_open_id = #{openId} and su.del_flag = '0'
group by su.user_id
</select>
<select id="selectSimpleById" resultMap="SmUserResult">

View File

@ -12,7 +12,11 @@ public interface UserAssembler {
/**
* 拼接用户店铺数量
* @param list
*/
void assembleStoreCount(List<SmUserVo> list);
/**
* 拼接用户设备数量
*/
void assembleDeviceCount(List<SmUserVo> list);
}

View File

@ -1,6 +1,11 @@
package com.ruoyi.ss.user.service.impl;
import com.ruoyi.common.utils.CollectionUtils;
import com.ruoyi.ss.device.domain.SmDeviceCountVO;
import com.ruoyi.ss.device.domain.SmDeviceQuery;
import com.ruoyi.ss.device.domain.enums.DeviceGroupBy;
import com.ruoyi.ss.device.domain.enums.DeviceGroupByTable;
import com.ruoyi.ss.device.service.ISmDeviceService;
import com.ruoyi.ss.store.domain.StoreCountVO;
import com.ruoyi.ss.store.domain.StoreQuery;
import com.ruoyi.ss.store.service.IStoreService;
@ -23,6 +28,9 @@ public class UserAssemblerImpl implements UserAssembler {
@Autowired
private IStoreService storeService;
@Autowired
private ISmDeviceService deviceService;
/**
* 拼接用户店铺数量
*
@ -41,4 +49,27 @@ public class UserAssemblerImpl implements UserAssembler {
user.setStoreCount(count == null ? 0 : count);
}
}
/**
* 拼接用户设备数量
*
* @param list
*/
@Override
public void assembleDeviceCount(List<SmUserVo> list) {
if (CollectionUtils.isEmptyElement(list)) {
return;
}
SmDeviceQuery query = new SmDeviceQuery();
query.setUserIds(list.stream().map(SmUserVo::getUserId).collect(Collectors.toList()));
query.setGroupBy(DeviceGroupBy.user_id.name());
query.setGroupByTable(DeviceGroupByTable.ss.name());
Map<Long, Integer> map = deviceService.selectCommonCountMap(query, SmDeviceCountVO::getUserId);
for (SmUserVo user : list) {
Integer count = map.get(user.getUserId());
user.setDeviceCount(count == null ? 0 : count);
}
}
}

View File

@ -8,6 +8,7 @@ import com.ruoyi.ss.account.domain.SmAccountBO;
import com.ruoyi.ss.account.domain.SmAccountQuery;
import com.ruoyi.ss.account.service.ISmAccountService;
import com.ruoyi.system.service.IVerificationCodeService;
import com.ruoyi.web.core.annotation.MchRequired;
import com.ruoyi.web.core.annotation.UserTypePermission;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@ -29,7 +30,7 @@ public class AppAccountController extends BaseController {
@Autowired
private IVerificationCodeService verificationCodeService;
@UserTypePermission({UserType.LANDLORD})
@MchRequired
@ApiOperation("添加收款账户")
@PostMapping
public AjaxResult addAccount(@RequestBody @Validated({ValidGroup.FrontCreate.class})SmAccountBO data) {

View File

@ -6,21 +6,18 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.JsonViewProfile;
import com.ruoyi.common.core.domain.ValidGroup;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.ss.device.domain.DeviceView;
import com.ruoyi.ss.device.domain.SmDevice;
import com.ruoyi.ss.device.domain.SmDeviceQuery;
import com.ruoyi.ss.device.service.DeviceAssembler;
import com.ruoyi.ss.device.service.DeviceValidator;
import com.ruoyi.ss.device.service.impl.DeviceValidatorImpl;
import com.ruoyi.ss.meterReadingRecord.domain.SmMeterReadingRecordQuery;
import com.ruoyi.ss.device.domain.enums.DevicePowerStatus;
import com.ruoyi.ss.device.domain.vo.SmDeviceVo;
import com.ruoyi.ss.device.service.ISmDeviceService;
import com.ruoyi.ss.meterReadingRecord.service.ISmMeterReadingRecordService;
import com.ruoyi.web.core.annotation.MchRequired;
import com.ruoyi.web.core.annotation.UserTypePermission;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
@ -60,16 +57,13 @@ public class AppDeviceController extends BaseController {
/**
* 修改设备
*/
@UserTypePermission({UserType.LANDLORD})
@MchRequired
@ApiOperation("商户修改设备")
@PutMapping
public AjaxResult edit(@RequestBody @Validated({ValidGroup.FrontUpdate.class}) SmDevice smDevice) {
SmDevice device = new SmDevice();
device.setDeviceId(smDevice.getDeviceId());
device.setStoreId(smDevice.getStoreId());
device.setPrice(smDevice.getPrice());
device.setOutageWay(smDevice.getOutageWay());
device.setTenantBearServiceFee(smDevice.getTenantBearServiceFee());
device.setRemark(smDevice.getRemark());
device.setNoticeWay(smDevice.getNoticeWay());
device.setEnableExpireNotice(smDevice.getEnableExpireNotice());
@ -107,40 +101,6 @@ public class AppDeviceController extends BaseController {
return success(smDeviceService.selectSmDeviceByDeviceId(deviceId));
}
@UserTypePermission({UserType.LANDLORD})
@ApiOperation("商户新增设备")
@PostMapping
public AjaxResult add(@RequestBody @Validated({ValidGroup.FrontCreate.class}) SmDevice smDevice) {
SmDevice insertDevice = new SmDevice();
insertDevice.setMac(smDevice.getMac());
insertDevice.setUserId(getUserId());
insertDevice.setDeviceName(smDevice.getMac());
return success(smDeviceService.insertSmDevice(insertDevice));
}
@UserTypePermission({UserType.TENANT})
@ApiOperation("获取租户设备信息")
@GetMapping("/tenant")
public TableDataInfo tenant(SmDeviceQuery dto) {
startPage();
dto.setTenantId(getUserId());
return getDataTable(smDeviceService.selectSmDeviceList(dto));
}
@UserTypePermission({UserType.TENANT})
@ApiOperation("租户解绑设备")
@PutMapping("/tenant/unbind/{deviceId}")
public AjaxResult tenantUnbind(@PathVariable @ApiParam("设备id") Long deviceId) {
return success(smDeviceService.tenantUnbind(getUserId(), deviceId));
}
@UserTypePermission({UserType.TENANT})
@ApiOperation("租户切换默认设备")
@PutMapping("/tenant/setDefault/{deviceId}")
public AjaxResult setDefault(@PathVariable @ApiParam("设备id") Long deviceId) {
return success(smDeviceService.setDefaultDevice(getUserId(), deviceId));
}
@ApiOperation("设备通断电")
@PutMapping("/{deviceId}/changePower")
public AjaxResult close(@PathVariable @ApiParam("设备id") Long deviceId, String status) {
@ -148,20 +108,22 @@ public class AppDeviceController extends BaseController {
return success(smDeviceService.changePowerStatus(deviceId, powerStatus ));
}
@MchRequired
@ApiOperation("绑定设备")
@PutMapping("/bind/{mac}")
public AjaxResult bind(@PathVariable @ApiParam("设备mac") String mac) {
return success(smDeviceService.bind(getUserId(), mac));
@PutMapping("/bind")
public AjaxResult bind(@RequestBody SmDevice device) {
return success(smDeviceService.bind(device.getStoreId(), device.getDeviceNo()));
}
@UserTypePermission({UserType.LANDLORD})
@MchRequired
@ApiOperation("商户解除设备绑定")
@DeleteMapping("/landlord/unbind/{deviceId}")
public AjaxResult landlordUnbind(@PathVariable @ApiParam("设备id") Long deviceId) {
return success(smDeviceService.landlordUnbind(getUserId(), deviceId));
@DeleteMapping("/mch/unbind/{deviceId}")
public AjaxResult mchUnbind(@PathVariable @ApiParam("设备id") Long deviceId) {
ServiceUtil.assertion(!deviceValidator.isBelong(deviceId, getUserId()), "这不是您的设备");
return success(smDeviceService.unbindStore(deviceId));
}
@UserTypePermission({UserType.LANDLORD})
@MchRequired
@ApiOperation("设备电量归零")
@PutMapping("{deviceId}/reset")
public AjaxResult reset(@PathVariable @ApiParam("设备id") Long deviceId) {
@ -175,14 +137,13 @@ public class AppDeviceController extends BaseController {
return success(smMeterReadingRecordService.selectCount(dto));
}
@UserTypePermission({UserType.LANDLORD})
@ApiOperation("设备充值电量")
@PostMapping("/addElectricity/{deviceId}")
public AjaxResult mockRecharge(@PathVariable @ApiParam("设备id") Long deviceId, @ApiParam("电量(度)") BigDecimal amount)
@MchRequired
@ApiOperation("设备充值时长")
@PostMapping("/addTime/{deviceId}")
public AjaxResult addTime(@PathVariable @ApiParam("设备id") Long deviceId, @ApiParam("电量(度)") BigDecimal amount)
{
SmDeviceVo device = smDeviceService.selectSmDeviceByDeviceId(deviceId);
ServiceUtil.assertion(device == null || !getUserId().equals(device.getUserId()), "设备不存在或您无权充值");
smDeviceService.addTime(deviceId, amount);
return success(true);
}

View File

@ -5,6 +5,7 @@ import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.UserType;
import com.ruoyi.ss.resetRecord.domain.SmResetRecordQuery;
import com.ruoyi.ss.resetRecord.service.ISmResetRecordService;
import com.ruoyi.web.core.annotation.MchRequired;
import com.ruoyi.web.core.annotation.UserTypePermission;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@ -24,7 +25,7 @@ public class AppResetRecordController extends BaseController {
@Autowired
private ISmResetRecordService smResetRecordService;
@UserTypePermission({UserType.LANDLORD})
@MchRequired
@ApiOperation("查询本人归零记录")
@GetMapping("/list")
public TableDataInfo list(SmResetRecordQuery dto) {

View File

@ -20,6 +20,7 @@ import com.ruoyi.ss.dashboard.BillCountVo;
import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import com.ruoyi.ss.transactionBill.service.TransactionAssembler;
import com.ruoyi.ss.transactionBill.service.TransactionBillValidator;
import com.ruoyi.web.core.annotation.MchRequired;
import com.ruoyi.web.core.annotation.UserTypePermission;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -107,7 +108,7 @@ public class AppTransactionBillController extends BaseController
return AjaxResult.success(bill);
}
@UserTypePermission({UserType.LANDLORD})
@MchRequired
@ApiOperation("获取商户统计信息")
@GetMapping("/landlordCount")
public AjaxResult landlordCount(@Validated({ValidGroup.Query.class}) TransactionBillQuery dto) {
@ -170,7 +171,7 @@ public class AppTransactionBillController extends BaseController
return AjaxResult.success(smTransactionBillService.cancelRecharge(billNo, TransactionBillStatus.CANCELED));
}
@UserTypePermission({UserType.LANDLORD})
@MchRequired
@ApiOperation("提现申请")
@PostMapping("/withdraw")
public AjaxResult withdraw(@RequestBody @Validated({ValidGroup.Withdraw.class}) TransactionBillBO data) {

View File

@ -113,7 +113,6 @@ public class SmDeviceController extends BaseController
@PutMapping
public AjaxResult edit(@RequestBody @Validated({ValidGroup.Update.class}) SmDevice smDevice)
{
deviceAssembler.setStore(smDevice); // 商户分组
return toAjax(smDeviceService.updateSmDevice(smDevice));
}

View File

@ -1,11 +1,13 @@
package com.ruoyi.web.controller.ss;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.ss.user.domain.SmUserQuery;
import com.ruoyi.ss.user.domain.SmUserVo;
import com.ruoyi.ss.user.service.UserAssembler;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -38,6 +40,9 @@ public class SmUserController extends BaseController
@Autowired
private ISmUserService smUserService;
@Autowired
private UserAssembler userAssembler;
/**
* 查询普通用户信息列表
*/
@ -47,6 +52,8 @@ public class SmUserController extends BaseController
{
startPage();
List<SmUserVo> list = smUserService.selectSmUserList(smUser);
userAssembler.assembleStoreCount(list);
userAssembler.assembleDeviceCount(list);
return getDataTable(list);
}
@ -81,7 +88,11 @@ public class SmUserController extends BaseController
@GetMapping(value = "/{userId}")
public AjaxResult getInfo(@PathVariable("userId") Long userId)
{
return success(smUserService.selectSmUserByUserId(userId));
SmUserVo user = smUserService.selectSmUserByUserId(userId);
List<SmUserVo> list = Collections.singletonList(user);
userAssembler.assembleStoreCount(list);
userAssembler.assembleDeviceCount(list);
return success(user);
}
/**

View File

@ -58,6 +58,17 @@ public class StoreController extends BaseController
return getDataTable(list);
}
/**
* ids查询商户列表
*/
@PreAuthorize("@ss.hasPermi('ss.store:list')")
@GetMapping("/listByIds/{ids}")
public AjaxResult listByIds(@PathVariable Long[] ids)
{
List<StoreVo> list = storeService.selectSmStoreListByIds(Arrays.asList(ids));
return success(list);
}
/**
* 导出商户列表
*/