feat(client): 实现账号设备试用期管理功能
- 新增设备试用期过期时间字段及管理接口 - 实现试用期状态检查与过期提醒逻辑 - 支持账号类型区分试用与付费用户 - 添加设备注册时自动设置3天试用期- 实现VIP状态刷新与过期类型判断 -优化账号列表查询支持按客户端用户名过滤 - 更新客户端设备管理支持试用期控制- 完善登录流程支持试用期状态提示 -修复设备离线通知缺少用户名参数问题 - 调整账号默认设置清除逻辑关联客户端用户名
This commit is contained in:
@@ -17,6 +17,8 @@ public class BanmaAccount extends BaseEntity {
|
||||
private String username;
|
||||
/** 登录密码(服务端刷新Token用,不对外返回) */
|
||||
private String password;
|
||||
/** 客户端账号用户名(关联client_account.username) */
|
||||
private String clientUsername;
|
||||
/** 访问 Token(客户端刷新后回写) */
|
||||
private String token;
|
||||
/** Token 过期时间(可选) */
|
||||
@@ -37,6 +39,8 @@ public class BanmaAccount extends BaseEntity {
|
||||
public void setUsername(String username) { this.username = username; }
|
||||
public String getPassword() { return password; }
|
||||
public void setPassword(String password) { this.password = password; }
|
||||
public String getClientUsername() { return clientUsername; }
|
||||
public void setClientUsername(String clientUsername) { this.clientUsername = clientUsername; }
|
||||
public String getToken() { return token; }
|
||||
public void setToken(String token) { this.token = token; }
|
||||
public Date getTokenExpireAt() { return tokenExpireAt; }
|
||||
|
||||
@@ -51,6 +51,10 @@ public class ClientAccount extends BaseEntity
|
||||
@Excel(name = "设备数量限制")
|
||||
private Integer deviceLimit;
|
||||
|
||||
/** 账号类型 */
|
||||
@Excel(name = "账号类型")
|
||||
private String accountType; // trial试用, paid付费
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
@@ -147,4 +151,14 @@ public class ClientAccount extends BaseEntity
|
||||
{
|
||||
return deviceLimit;
|
||||
}
|
||||
|
||||
public void setAccountType(String accountType)
|
||||
{
|
||||
this.accountType = accountType;
|
||||
}
|
||||
|
||||
public String getAccountType()
|
||||
{
|
||||
return accountType;
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,9 @@ public class ClientDevice extends BaseEntity {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "最近在线", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date lastActiveAt;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "试用期过期时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date trialExpireTime;
|
||||
|
||||
public Long getId() { return id; }
|
||||
public void setId(Long id) { this.id = id; }
|
||||
@@ -49,6 +52,8 @@ public class ClientDevice extends BaseEntity {
|
||||
public void setLocation(String location) { this.location = location; }
|
||||
public Date getLastActiveAt() { return lastActiveAt; }
|
||||
public void setLastActiveAt(Date lastActiveAt) { this.lastActiveAt = lastActiveAt; }
|
||||
public Date getTrialExpireTime() { return trialExpireTime; }
|
||||
public void setTrialExpireTime(Date trialExpireTime) { this.trialExpireTime = trialExpireTime; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ruoyi.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.ruoyi.system.domain.BanmaAccount;
|
||||
|
||||
/**
|
||||
@@ -12,7 +13,7 @@ public interface BanmaAccountMapper {
|
||||
int insert(BanmaAccount entity);
|
||||
int update(BanmaAccount entity);
|
||||
int deleteById(Long id);
|
||||
int clearDefault();
|
||||
int clearDefault(@Param("clientUsername") String clientUsername);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
package com.ruoyi.system.mapper;
|
||||
|
||||
import com.ruoyi.system.domain.ClientDevice;
|
||||
import io.lettuce.core.dynamic.annotation.Param;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ClientDeviceMapper {
|
||||
ClientDevice selectByDeviceId(String deviceId);
|
||||
ClientDevice selectByDeviceId(@Param("deviceId") String deviceId);
|
||||
ClientDevice selectByDeviceIdAndUsername(@Param("deviceId") String deviceId, @Param("username") String username);
|
||||
List<ClientDevice> selectByUsername(@Param("username") String username);
|
||||
List<ClientDevice> selectOnlineDevices();
|
||||
int insert(ClientDevice device);
|
||||
int updateByDeviceId(ClientDevice device);
|
||||
int deleteByDeviceId(String deviceId);
|
||||
int countByUsername(String username);
|
||||
int updateByDeviceIdAndUsername(ClientDevice device);
|
||||
int deleteByDeviceId(@Param("deviceId") String deviceId);
|
||||
int countByUsername(@Param("username") String username);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,14 @@ public class BanmaAccountServiceImpl implements IBanmaAccountService {
|
||||
|
||||
@Override
|
||||
public List<BanmaAccount> listSimple() {
|
||||
List<BanmaAccount> list = mapper.selectList(new BanmaAccount());
|
||||
return listSimple(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BanmaAccount> listSimple(String clientUsername) {
|
||||
BanmaAccount query = new BanmaAccount();
|
||||
query.setClientUsername(clientUsername);
|
||||
List<BanmaAccount> list = mapper.selectList(query);
|
||||
// 隐藏密码
|
||||
for (BanmaAccount a : list) { a.setPassword(null); }
|
||||
return list;
|
||||
@@ -34,13 +41,25 @@ public class BanmaAccountServiceImpl implements IBanmaAccountService {
|
||||
|
||||
@Override
|
||||
public Long saveOrUpdate(BanmaAccount entity) {
|
||||
return saveOrUpdate(entity, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long saveOrUpdate(BanmaAccount entity, String clientUsername) {
|
||||
// 设置客户端用户名
|
||||
if (clientUsername != null) {
|
||||
entity.setClientUsername(clientUsername);
|
||||
}
|
||||
|
||||
if (entity.getId() == null) {
|
||||
mapper.insert(entity);
|
||||
} else {
|
||||
mapper.update(entity);
|
||||
}
|
||||
if (Objects.equals(entity.getIsDefault(), 1)) {
|
||||
mapper.clearDefault();
|
||||
|
||||
// 如果设为默认,则清除该客户端的其他默认账号
|
||||
if (Objects.equals(entity.getIsDefault(), 1) && entity.getClientUsername() != null) {
|
||||
mapper.clearDefault(entity.getClientUsername());
|
||||
BanmaAccount only = new BanmaAccount();
|
||||
only.setId(entity.getId());
|
||||
only.setIsDefault(1);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<result property="name" column="name"/>
|
||||
<result property="username" column="username"/>
|
||||
<result property="password" column="password"/>
|
||||
<result property="clientUsername" column="client_username"/>
|
||||
<result property="token" column="token"/>
|
||||
<result property="tokenExpireAt" column="token_expire_at"/>
|
||||
<result property="isDefault" column="is_default"/>
|
||||
@@ -19,7 +20,7 @@
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, name, username, password, token, token_expire_at, is_default, status, remark, create_by, create_time, update_by, update_time
|
||||
id, name, username, password, client_username, token, token_expire_at, is_default, status, remark, create_by, create_time, update_by, update_time
|
||||
</sql>
|
||||
|
||||
<select id="selectById" parameterType="long" resultMap="BanmaAccountResult">
|
||||
@@ -29,6 +30,7 @@
|
||||
<select id="selectList" parameterType="com.ruoyi.system.domain.BanmaAccount" resultMap="BanmaAccountResult">
|
||||
select <include refid="Base_Column_List"/> from banma_account
|
||||
<where>
|
||||
<if test="clientUsername != null and clientUsername != ''"> and client_username = #{clientUsername}</if>
|
||||
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
|
||||
<if test="username != null and username != ''"> and username like concat('%', #{username}, '%')</if>
|
||||
<if test="status != null"> and status = #{status}</if>
|
||||
@@ -42,6 +44,7 @@
|
||||
<if test="name != null">name,</if>
|
||||
<if test="username != null">username,</if>
|
||||
<if test="password != null">password,</if>
|
||||
<if test="clientUsername != null">client_username,</if>
|
||||
<if test="token != null">token,</if>
|
||||
<if test="tokenExpireAt != null">token_expire_at,</if>
|
||||
<if test="isDefault != null">is_default,</if>
|
||||
@@ -54,6 +57,7 @@
|
||||
<if test="name != null">#{name},</if>
|
||||
<if test="username != null">#{username},</if>
|
||||
<if test="password != null">#{password},</if>
|
||||
<if test="clientUsername != null">#{clientUsername},</if>
|
||||
<if test="token != null">#{token},</if>
|
||||
<if test="tokenExpireAt != null">#{tokenExpireAt},</if>
|
||||
<if test="isDefault != null">#{isDefault},</if>
|
||||
@@ -70,6 +74,7 @@
|
||||
<if test="name != null">name=#{name},</if>
|
||||
<if test="username != null">username=#{username},</if>
|
||||
<if test="password != null">password=#{password},</if>
|
||||
<if test="clientUsername != null">client_username=#{clientUsername},</if>
|
||||
<if test="token != null">token=#{token},</if>
|
||||
<if test="tokenExpireAt != null">token_expire_at=#{tokenExpireAt},</if>
|
||||
<if test="isDefault != null">is_default=#{isDefault},</if>
|
||||
@@ -82,7 +87,10 @@
|
||||
</update>
|
||||
|
||||
<update id="clearDefault">
|
||||
update banma_account set is_default = 0 where is_default = 1
|
||||
update banma_account set is_default = 0 where is_default = 1
|
||||
<if test="clientUsername != null and clientUsername != ''">
|
||||
and client_username = #{clientUsername}
|
||||
</if>
|
||||
</update>
|
||||
|
||||
<delete id="deleteById" parameterType="long">
|
||||
|
||||
@@ -15,6 +15,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="remark" column="remark" />
|
||||
<result property="permissions" column="permissions" />
|
||||
<result property="deviceLimit" column="device_limit" />
|
||||
<result property="accountType" column="account_type" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
@@ -23,7 +24,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<sql id="selectClientAccountVo">
|
||||
select id, account_name, username, password, status, expire_time,
|
||||
allowed_ip_range, remark, permissions, device_limit, create_by, create_time, update_by, update_time
|
||||
allowed_ip_range, remark, permissions, device_limit, account_type, create_by, create_time, update_by, update_time
|
||||
from client_account
|
||||
</sql>
|
||||
|
||||
@@ -59,6 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="remark != null">remark,</if>
|
||||
<if test="permissions != null">permissions,</if>
|
||||
<if test="deviceLimit != null">device_limit,</if>
|
||||
<if test="accountType != null">account_type,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
create_time
|
||||
</trim>
|
||||
@@ -72,6 +74,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="remark != null">#{remark},</if>
|
||||
<if test="permissions != null">#{permissions},</if>
|
||||
<if test="deviceLimit != null">#{deviceLimit},</if>
|
||||
<if test="accountType != null">#{accountType},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
sysdate()
|
||||
</trim>
|
||||
@@ -89,6 +92,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
<if test="permissions != null">permissions = #{permissions},</if>
|
||||
<if test="deviceLimit != null">device_limit = #{deviceLimit},</if>
|
||||
<if test="accountType != null">account_type = #{accountType},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
update_time = sysdate()
|
||||
</trim>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<result property="ip" column="ip"/>
|
||||
<result property="location" column="location"/>
|
||||
<result property="lastActiveAt" column="last_active_at"/>
|
||||
<result property="trialExpireTime" column="trial_expire_time"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
@@ -19,13 +20,17 @@
|
||||
select * from client_device where device_id = #{deviceId}
|
||||
</select>
|
||||
|
||||
<select id="selectByDeviceIdAndUsername" resultMap="ClientDeviceMap">
|
||||
select * from client_device where device_id = #{deviceId} and username = #{username}
|
||||
</select>
|
||||
|
||||
<select id="selectByUsername" resultMap="ClientDeviceMap">
|
||||
select * from client_device where username = #{username} and status != 'removed' order by update_time desc
|
||||
</select>
|
||||
|
||||
<insert id="insert" parameterType="com.ruoyi.system.domain.ClientDevice" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into client_device(username, device_id, name, os, status, ip, location, last_active_at, create_time, update_time)
|
||||
values(#{username}, #{deviceId}, #{name}, #{os}, #{status}, #{ip}, #{location}, #{lastActiveAt}, now(), now())
|
||||
insert into client_device(username, device_id, name, os, status, ip, location, last_active_at, trial_expire_time, create_time, update_time)
|
||||
values(#{username}, #{deviceId}, #{name}, #{os}, #{status}, #{ip}, #{location}, #{lastActiveAt}, #{trialExpireTime}, now(), now())
|
||||
</insert>
|
||||
|
||||
<update id="updateByDeviceId" parameterType="com.ruoyi.system.domain.ClientDevice">
|
||||
@@ -37,10 +42,26 @@
|
||||
ip = #{ip},
|
||||
location = #{location},
|
||||
last_active_at = #{lastActiveAt},
|
||||
trial_expire_time = #{trialExpireTime},
|
||||
update_time = now()
|
||||
where device_id = #{deviceId}
|
||||
</update>
|
||||
|
||||
<update id="updateByDeviceIdAndUsername" parameterType="com.ruoyi.system.domain.ClientDevice">
|
||||
update client_device
|
||||
<set>
|
||||
<if test="name != null">name = #{name},</if>
|
||||
<if test="os != null">os = #{os},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="ip != null">ip = #{ip},</if>
|
||||
<if test="location != null">location = #{location},</if>
|
||||
<if test="lastActiveAt != null">last_active_at = #{lastActiveAt},</if>
|
||||
<if test="trialExpireTime != null">trial_expire_time = #{trialExpireTime},</if>
|
||||
update_time = now()
|
||||
</set>
|
||||
where device_id = #{deviceId} and username = #{username}
|
||||
</update>
|
||||
|
||||
<delete id="deleteByDeviceId">
|
||||
delete from client_device where device_id = #{deviceId}
|
||||
</delete>
|
||||
|
||||
Reference in New Issue
Block a user