1.设置多设备登录配置为 false

2.修改主播分页查询为XML查询
3.添加查询当前用户部门下所有用户接口
4.新建国家信息实体类
5.添加批量更新主播接口
This commit is contained in:
2025-06-23 21:49:21 +08:00
parent 26be7fb12b
commit c547092e6b
12 changed files with 324 additions and 24 deletions

View File

@@ -57,6 +57,14 @@ public class NewHostsController {
return success(true);
}
@PutMapping("/batch-update")
@Operation(summary = "批量更新主播数据")
@PreAuthorize("@ss.hasPermission('server:new-hosts:update')")
public CommonResult<Boolean> updateNewHosts(@Valid @RequestBody List<NewHostsSaveReqVO> updateReqVO) {
newHostsService.batchUpdateNewHosts(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除主播数据")
@Parameter(name = "id", description = "编号", required = true)

View File

@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.tkdata.controller.admin.newhosts.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -48,9 +49,79 @@ public class NewHostsPageReqVO extends PageParam {
@Schema(description = "数据插入时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
private LocalDateTime createTime;
@Schema(description = "用户 Id", example = "10967")
private Long userId;
/**
* 昨日金币最大值
*/
@Schema(description = "昨日金币查询最大值", example = "5000")
private Integer yesterdayCoinsMax;
/**
* 昨日金币最小值
*/
@Schema(description = "昨日金币查询最小值", example = "500")
private Integer yesterdayCoinsMin;
/**
* 关注数量最大值
*/
@Schema(description = "关注数量查询最大值", example = "1000")
private Integer fllowernumMax;
/**
* 关注数量最小值
*/
@Schema(description = "关注数量查询最小值", example = "100")
private Integer fllowernumMin;
/**
* 粉丝数量最大值
*/
@Schema(description = "粉丝数量查询最大值", example = "50000")
private Integer fansMax;
/**
* 粉丝数量最小值
*/
@Schema(description = "粉丝数量查询最小值", example = "1000")
private Integer fansMin;
@Schema(description = "在线人数最大值", example = "5000")
private Integer onlineFansMax;
@Schema(description = "在线人数最小值", example = " 10")
private Integer onlineFansMin;
/**
* 主播金币最大值
*/
@Schema(description = "主播金币查询最大值", example = "10000")
private Integer hostsCoinsMax;
/**
* 主播金币最小值
*/
@Schema(description = "主播金币查询最小值", example = "1000")
private Integer hostsCoinsMin;
/**
* 排序规则
*/
@Schema(description = "排序方式(asc/desc)", example = "desc")
private String sort;
/**
* 按照何种业务排序
*/
@Schema(description = "排序字段(createTime/hostsCoins/fans等)", example = "hostsCoins")
private String sortName;
private Long tenantId;
}

View File

@@ -0,0 +1,54 @@
package cn.iocoder.yudao.module.tkdata.dal.dataobject.countryinfo;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 国家与地区信息统计 DO
*
* @author 芋道源码
*/
@TableName("server_country_info")
@KeySequence("server_country_info_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CountryInfoDO extends BaseDO {
/**
* 主键id无业务含义
*/
@TableId
private Integer id;
/**
* 业务区与地区码
*/
private String countryGroup;
/**
* 业务区与地区名称
*/
private String countryGroupName;
/**
* 国家id
*/
@TableId(type = IdType.INPUT)
private String countryId;
/**
* 国家名称
*/
private String countryName;
/**
* 语言
*/
private String language;
/**
* 语言中文
*/
private String languageName;
}

View File

@@ -1,13 +1,20 @@
package cn.iocoder.yudao.module.tkdata.dal.mysql.newhosts;
import cn.iocoder.yudao.module.tkdata.dal.dataobject.countryinfo.CountryInfoDO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.tkdata.dal.dataobject.newhosts.NewHostsDO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.tkdata.controller.admin.newhosts.vo.*;
import org.apache.ibatis.annotations.Param;
/**
* 主播数据 Mapper
@@ -17,22 +24,23 @@ import cn.iocoder.yudao.module.tkdata.controller.admin.newhosts.vo.*;
@Mapper
public interface NewHostsMapper extends BaseMapperX<NewHostsDO> {
default PageResult<NewHostsDO> selectPage(NewHostsPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<NewHostsDO>()
.eqIfPresent(NewHostsDO::getHostsId, reqVO.getHostsId())
.eqIfPresent(NewHostsDO::getHostsLevel, reqVO.getHostsLevel())
.eqIfPresent(NewHostsDO::getHostsCoins, reqVO.getHostsCoins())
.eqIfPresent(NewHostsDO::getInvitationType, reqVO.getInvitationType())
.eqIfPresent(NewHostsDO::getOnlineFans, reqVO.getOnlineFans())
.eqIfPresent(NewHostsDO::getFans, reqVO.getFans())
.eqIfPresent(NewHostsDO::getFllowernum, reqVO.getFllowernum())
.eqIfPresent(NewHostsDO::getYesterdayCoins, reqVO.getYesterdayCoins())
.eqIfPresent(NewHostsDO::getCountry, reqVO.getCountry())
.eqIfPresent(NewHostsDO::getHostsKind, reqVO.getHostsKind())
.eqIfPresent(NewHostsDO::getIsAssigned, reqVO.getIsAssigned())
.betweenIfPresent(NewHostsDO::getCreateTime, reqVO.getCreateTime())
.eqIfPresent(NewHostsDO::getUserId, reqVO.getUserId())
.orderByDesc(NewHostsDO::getId));
}
// default PageResult<NewHostsDO> selectPage(NewHostsPageReqVO reqVO) {
// return selectPage(reqVO, new LambdaQueryWrapperX<NewHostsDO>()
// .eqIfPresent(NewHostsDO::getHostsId, reqVO.getHostsId())
// .eqIfPresent(NewHostsDO::getHostsLevel, reqVO.getHostsLevel())
// .eqIfPresent(NewHostsDO::getHostsCoins, reqVO.getHostsCoins())
// .eqIfPresent(NewHostsDO::getInvitationType, reqVO.getInvitationType())
// .eqIfPresent(NewHostsDO::getOnlineFans, reqVO.getOnlineFans())
// .eqIfPresent(NewHostsDO::getFans, reqVO.getFans())
// .eqIfPresent(NewHostsDO::getFllowernum, reqVO.getFllowernum())
// .eqIfPresent(NewHostsDO::getYesterdayCoins, reqVO.getYesterdayCoins())
// .eqIfPresent(NewHostsDO::getCountry, reqVO.getCountry())
// .eqIfPresent(NewHostsDO::getHostsKind, reqVO.getHostsKind())
// .eqIfPresent(NewHostsDO::getIsAssigned, reqVO.getIsAssigned())
// .betweenIfPresent(NewHostsDO::getCreateTime, reqVO.getCreateTime())
// .eqIfPresent(NewHostsDO::getUserId, reqVO.getUserId())
// .orderByDesc(NewHostsDO::getId));
// }
IPage<NewHostsDO> selectPageWithXML(IPage<NewHostsDO> page,@Param("req") NewHostsPageReqVO reqVO);
}

View File

@@ -61,4 +61,5 @@ public interface NewHostsService {
*/
PageResult<NewHostsDO> getNewHostsPage(NewHostsPageReqVO pageReqVO);
void batchUpdateNewHosts(@Valid List<NewHostsSaveReqVO> updateReqVO);
}

View File

@@ -1,12 +1,15 @@
package cn.iocoder.yudao.module.tkdata.service.newhosts;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.tkdata.controller.admin.newhosts.vo.AllocationHostsSaveReqVO;
import cn.iocoder.yudao.module.tkdata.controller.admin.newhosts.vo.NewHostsPageReqVO;
import cn.iocoder.yudao.module.tkdata.controller.admin.newhosts.vo.NewHostsSaveReqVO;
import cn.iocoder.yudao.module.tkdata.dal.dataobject.newhosts.NewHostsDO;
import cn.iocoder.yudao.module.tkdata.dal.mysql.newhosts.NewHostsMapper;
import cn.iocoder.yudao.module.tkdata.enums.ErrorCodeConstants;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@@ -88,8 +91,21 @@ public class NewHostsServiceImpl implements NewHostsService {
@Override
public PageResult<NewHostsDO> getNewHostsPage(NewHostsPageReqVO pageReqVO) {
PageResult<NewHostsDO> newHostsDOPageResult = newHostsMapper.selectPage(pageReqVO);
return newHostsDOPageResult;
pageReqVO.setTenantId(TenantContextHolder.getTenantId());
IPage<NewHostsDO> iPage = new Page<>(pageReqVO.getPageNo(),pageReqVO.getPageSize());
IPage<NewHostsDO> newHostsDOIPage = newHostsMapper.selectPageWithXML(iPage,pageReqVO);
return new PageResult<>(newHostsDOIPage.getRecords(),newHostsDOIPage.getTotal());
}
@Override
public void batchUpdateNewHosts(List<NewHostsSaveReqVO> updateReqVO) {
ArrayList<NewHostsDO> newHostsDOS = new ArrayList<>();
for (NewHostsSaveReqVO newHostsSaveReqVO : updateReqVO) {
NewHostsDO newHostsDO = new NewHostsDO();
BeanUtils.copyProperties(newHostsSaveReqVO,newHostsDO);
newHostsDOS.add(newHostsDO);
}
newHostsMapper.updateBatch(newHostsDOS);
}
}

View File

@@ -9,4 +9,121 @@
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<select id="selectPageWithXML" resultType="cn.iocoder.yudao.module.tkdata.dal.dataobject.newhosts.NewHostsDO">
select ns.id,hosts_id, hosts_level, hosts_coins, Invitation_type, fans, fllowernum,
yesterday_coins,ns.create_time, country, online_fans,hosts_kind ,is_assigned from server_new_hosts ns join server_country_info ci ON ns.country = ci.country_name
WHERE tenant_id =#{req.tenantId,jdbcType=BIGINT}
<!-- 主播国家筛选 -->
<if test="req.country!= '' and req.country != null">
and ci.country_group_name =#{req.country,jdbcType=VARCHAR}
</if>
<!-- 按照入库时间筛选主播 -->
<if test="req.createTime != null">
and DATE(ns.create_time) =#{req.createTime}
</if>
<!-- 主播 Id 模糊搜索 -->
<if test="req.hostsId != '' and req.hostsId != null ">
and ns.hosts_id like concat(#{req.hostsId,jdbcType=VARCHAR},'%')
</if>
<!-- 是否分配筛选 -->
<if test="req.isAssigned != null and req.isAssigned != ''">
and ns.is_assigned =#{req.isAssigned,jdbcType=INTEGER}
</if>
<!-- 主播等级筛选 -->
<if test="req.hostsLevel != null and req.hostsLevel != ''">
and ns.hosts_level =#{req.hostsLevel,jdbcType=VARCHAR}
</if>
<!-- 今日主播金币筛选 -->
<if test="req.hostsCoinsMin != null and req.hostsCoinsMax == null and req.hostsCoinsMax != '' ">
and ns.hosts_coins >=#{req.hostsCoinsMin,jdbcType=INTEGER}
</if>
<if test="req.hostsCoinsMax != null and req.hostsCoinsMin == null and req.hostsCoinsMin !='' ">
and ns.hosts_coins &lt;=#{req.hostsCoinsMax,jdbcType=INTEGER}
</if>
<if test="req.hostsCoinsMin != null and req.hostsCoinsMax != null " >
and ns.hosts_coins between #{req.hostsCoinsMin,jdbcType=INTEGER} and #{req.hostsCoinsMax,jdbcType=INTEGER}
</if>
<!-- 昨日主播金币筛选 -->
<if test="req.yesterdayCoinsMin != null and req.yesterdayCoinsMax == null and req.yesterdayCoinsMax != ''">
and ns.yesterday_coins >=#{req.yesterdayCoinsMin,jdbcType=INTEGER}
</if>
<if test="req.yesterdayCoinsMax != null and req.yesterdayCoinsMin == null and req.yesterdayCoinsMin != '' ">
and ns.yesterday_coins &lt;=#{req.yesterdayCoinsMax,jdbcType=INTEGER}
</if>
<if test="req.yesterdayCoinsMin != null and req.yesterdayCoinsMax != null " >
and ns.yesterday_coins between #{req.yesterdayCoinsMin,jdbcType=INTEGER} and #{req.yesterdayCoinsMax,jdbcType=INTEGER}
</if>
<!-- 主播粉丝数筛选-->
<if test="req.fansMin != null and req.fansMax == null and req.fansMax != ''">
and ns.fans >=#{req.fansMin,jdbcType=INTEGER}
</if>
<if test="req.fansMax != null and req.fansMin == null and req.fansMin != '' ">
and ns.fans &lt;=#{req.fansMax,jdbcType=INTEGER}
</if>
<if test="req.fansMin != null and req.fansMax != null " >
and ns.fans between #{req.fansMin,jdbcType=INTEGER} and #{req.fansMax,jdbcType=INTEGER}
</if>
<!-- 主播关注筛选-->
<if test="req.fllowernumMin != null and req.fllowernumMax == null and req.fllowernumMax != ''">
and ns.fllowernum >=#{req.fllowernumMin,jdbcType=INTEGER}
</if>
<if test="req.fllowernumMax != null and req.fllowernumMin == null and req.fllowernumMin != ''">
and ns.fllowernum &lt;=#{req.fllowernumMax,jdbcType=INTEGER}
</if>
<if test="req.fllowernumMin != null and req.fllowernumMax != null " >
and ns.fllowernum between #{req.fllowernumMin,jdbcType=INTEGER} and #{req.fllowernumMax,jdbcType=INTEGER}
</if>
<!-- 主播在线人数筛选-->
<if test="req.onlineFansMin != null and req.onlineFansMax == null and req.onlineFansMax != '' ">
and ns.online_fans >=#{req.onlineFansMin,jdbcType=INTEGER}
</if>
<if test="req.onlineFansMax != null and req.onlineFansMin == null and req.onlineFansMin != ''">
and ns.online_fans &lt;= #{req.onlineFansMax,jdbcType=INTEGER}
</if>
<if test="req.onlineFansMin != null and req.onlineFansMax != null " >
and ns.online_fans between #{req.onlineFansMin,jdbcType=INTEGER} and #{req.onlineFansMax,jdbcType=INTEGER}
</if>
<!-- 邀请类筛选 -->
<if test="req.invitationType != null">
and ns.Invitation_type =#{req.invitationType,jdbcType=INTEGER}
</if>
<!-- 排序类型 -->
order by
<choose>
<!-- 传空和默认的情况下按照时间降序排序 -->
<when test="req.sortName == '' and req.sortName == null">
ns.create_time desc
</when>
<!-- sortNmae 有值的情况下排序 -->
<when test="req.sortName != null and req.sort != null ">
<if test="req.sortName == 'createTime' and req.sort != null">
ns.create_time ${req.sort}
</if>
<!-- 昨日主播金币条件排序 -->
<if test="req.sortName == 'yesterdayCoins' and req.sort != null">
ns.yesterday_coins ${req.sort}
</if>
<!-- 主播金币条件排序 -->
<if test="req.sortName == 'hostsCoins' and req.sort != null">
ns.hosts_coins ${req.sort}
</if>
<!-- 主播粉丝条件排序 -->
<if test="req.sortName == 'fans' and req.sort != null">
ns.fans ${req.sort}
</if>
<!-- 主播关注数量排序 -->
<if test="req.sortName == 'fllowernum' and req.sort != null">
ns.fllowernum ${req.sort}
</if>
<!-- 主播直播间在线数量排序 -->
<if test="req.sortName == 'onlineFans' and req.sort != null">
ns.online_fans ${req.sort}
</if>
</when>
<otherwise>
ns.create_time desc
</otherwise>
</choose>
</select>
</mapper>

View File

@@ -27,9 +27,7 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -169,4 +167,20 @@ public class UserController {
return success(userService.importUserList(list, updateSupport));
}
@GetMapping({"/list-all-simple-dept"})
@Operation(summary = "获取部门下所有用户", description = "只包含被开启的用户,主要用于前端的下拉选项")
public CommonResult<List<UserSimpleRespVO>> getSimpleUserListWithDept(@RequestParam Long deptId) {
// List<AdminUserDO> list = userService.getUserListByStatus(CommonStatusEnum.ENABLE.getStatus());
List<AdminUserDO> list = userService.getUserListByStatusAndDept(CommonStatusEnum.ENABLE.getStatus(),deptId);
List<AdminUserDO> userDOList = new ArrayList<>();
for (AdminUserDO adminUserDO : list) {
if (Objects.equals(deptId, adminUserDO.getDeptId())) {
userDOList.add(adminUserDO);
}
}
// 拼接数据
Map<Long, DeptDO> deptMap = deptService.getDeptMap(
convertList(userDOList, AdminUserDO::getDeptId));
return success(UserConvert.INSTANCE.convertSimpleList(userDOList, deptMap));
}
}

View File

@@ -48,4 +48,9 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
return selectList(AdminUserDO::getDeptId, deptIds);
}
default List<AdminUserDO> getUserListByStatusAndDept(Integer status, Long deptId){
return selectList(new LambdaQueryWrapperX<AdminUserDO>()
.eq(AdminUserDO::getStatus, status)
.eq(AdminUserDO::getDeptId, deptId));
}
}

View File

@@ -67,7 +67,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
@Transactional(rollbackFor = Exception.class)
public OAuth2AccessTokenDO createAccessToken(Long userId, Integer userType, String clientId, List<String> scopes) {
// 在 yaml multiple-device-login = True 时 删除用户上次登录令牌,实现单设备登录
if (multipleDeviceLoginConfig){
if (!multipleDeviceLoginConfig){
removeAccessTokenByUserId(userId);
}
OAuth2ClientDO clientDO = oauth2ClientService.validOAuthClientFromCache(clientId);

View File

@@ -207,4 +207,5 @@ public interface AdminUserService {
*/
boolean isPasswordMatch(String rawPassword, String encodedPassword);
List<AdminUserDO> getUserListByStatusAndDept(Integer status, Long deptId);
}

View File

@@ -515,6 +515,11 @@ public class AdminUserServiceImpl implements AdminUserService {
// return passwordEncoder.matches(rawPassword, encodedPassword);
}
@Override
public List<AdminUserDO> getUserListByStatusAndDept(Integer status, Long deptId) {
return userMapper.getUserListByStatusAndDept(status,deptId);
}
/**
* 对密码进行加密
*