Compare commits

...

8 Commits

Author SHA1 Message Date
曹鹏飞 591d9cd518 fix(admin): 修复管理员用户服务中的返回值问题
- 在AdminUserServiceImpl中添加缺失的return语句
- 确保方法正确返回userVOS列表
- 解决了树形结构绑定功能的逻辑错误
2026-01-16 10:11:16 +08:00
曹鹏飞 fbea0c26a6 feat(admin): 添加新搜索账号功能和用户管理相关字段
- 在AdminUserController中新增searchAccountNew接口用于搜索账号
- 在AdminUserServiceImpl中实现searchNew方法,支持按部门ID和其他条件搜索用户
- 为AdminUserVO添加children字段支持树形结构展示
- 在AppUser实体中新增departmentId和regionTypeId字段
- 在多个控制器和请求对象中添加部门ID和地区类型的验证和映射
- 更新数据库映射文件以包含新的字段查询
- 优化用户搜索逻辑,支持部门层级结构的递归绑定
- 添加事务注解确保数据一致性操作
2026-01-15 18:01:37 +08:00
曹鹏飞 a134b18dc5 Merge branch 'refs/heads/feature/gongfu' into feature/data-permission 2026-01-15 15:55:26 +08:00
曹鹏飞 27d6fe13e8 feat(AppUserMapper): 添加用户类型字段映射
- 在查询结果中新增 userType 字段映射为 type
- 保持现有所有用户信息字段的映射关系不变
- 优化用户申请表的数据查询结构
2026-01-15 15:54:39 +08:00
曹鹏飞 2ecfd9ca6b Merge branch 'feature/gongfu' into feature/data-permission 2026-01-15 15:30:11 +08:00
曹鹏飞 33365d5aa9 fix(filter): 修复应用版本过滤器逻辑
- 添加else分支确保请求正常通过过滤器链
- 防止过滤器在特定条件下阻断正常请求处理流程
2026-01-15 15:29:59 +08:00
曹鹏飞 1509b20788 Merge branch 'feature/gongfu' into feature/data-permission 2026-01-15 15:16:09 +08:00
曹鹏飞 7cf1dfcf9f fix(filter): 修复App-Version参数缺失导致的接口访问问题
- 添加白名单配置,排除部分遗漏App-Version参数的前端接口
- 对getTicket、uploadSingleFile、getInfoById接口跳过版本校验
- 解决iOS打包重新审核期间的接口兼容性问题
- 保留原有版本校验逻辑,仅对白名单接口进行特殊处理
2026-01-15 15:15:30 +08:00
16 changed files with 264 additions and 19 deletions

View File

@ -371,4 +371,14 @@ public class AdminUserController extends ControllerBase {
emailService.sendEmail(request.getEmail(), subject, content);
return ApiResult.success();
}
/**
* 搜索账号
* @param request 请求参数
*/
@PostMapping("searchAccountNew")
@ApiMark(moduleName = "账号管理", apiName = "搜索账号(新)")
public ApiResult<List<AdminUserVO>> searchAccountNew(@Valid @RequestBody SearchAccountRequest request) {
return ApiResult.success(adminUserService.searchNew(request));
}
}

View File

@ -200,6 +200,7 @@ public class AppUserController extends ControllerBase {
* 更新代理商账号
* @param request 请求参数
*/
@Transactional
@PostMapping("updateAppUser")
@MethodInfoMark(value = "更新代理商账号", menuName = "代理商管理")
@ApiMark(moduleName = "代理商管理", apiName = "更新代理商账号")
@ -224,6 +225,8 @@ public class AppUserController extends ControllerBase {
.setAreaId(request.getAreaId())
.setTitleId(request.getTitleId())
.setCompanyId(StrUtil.join(",", request.getCompanyIds()))
.setDepartmentId(request.getDepartmentId())
.setRegionTypeId(request.getRegionTypeId())
.setUpdateBy(AdminUserUtil.getUserName())
.setUpdateTime(LocalDateTime.now());
if (!Objects.equals(user.getState(), UserState.ToBeActivated.getState()) && Objects.nonNull(request.getEnable())) {
@ -271,11 +274,20 @@ public class AppUserController extends ControllerBase {
.setLanguageCode(request.getLanguageCode())
.setTitleId(request.getTitleId())
.setCompanyId(StrUtil.join(",", request.getCompanyIds()))
.setDepartmentId(request.getDepartmentId())
.setRegionTypeId(request.getRegionTypeId())
.setUpdateBy(AdminUserUtil.getUserName())
.setUpdateTime(LocalDateTime.now());
if (!Objects.equals(user.getState(), UserState.ToBeActivated.getState()) && Objects.nonNull(request.getEnable())) {
user.setState(request.getEnable() ? UserState.Activated.getState() : UserState.Disabled.getState());
}
if (Objects.equals(user.getRegionTypeId(), request.getRegionTypeId())) {
List<AppUser> children = appUserService.getChildren(user);
appUserService.lambdaUpdate()
.set(AppUser::getRegionTypeId, request.getRegionTypeId())
.in(AppUser::getId, children.stream().map(AppUser::getId).collect(Collectors.toList()))
.update();
}
appUserService.updateById(user);
}

View File

@ -83,4 +83,10 @@ public class CustomerDTO {
* 区域列表
*/
private List<CustomerAreaDTO> areaList;
/**
* 是否报价对象
*/
@NotNull(message = "是否报价对象不能为空")
private Boolean quotationUse;
}

View File

@ -1,5 +1,6 @@
package com.nflg.mobilebroken.common.pojo;
import com.nflg.mobilebroken.common.pojo.vo.AdminUserVO;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
@ -26,6 +27,10 @@ public class PageData<T> implements Serializable {
//总页数
private int totalPages;
public static PageData<AdminUserVO> empty() {
return new PageData<>();
}
public int getTotalPages() {
return total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
}

View File

@ -3,6 +3,8 @@ package com.nflg.mobilebroken.common.pojo.request;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class ApproveAppUserApplyforRequest {
@ -13,4 +15,10 @@ public class ApproveAppUserApplyforRequest {
@JsonIgnore
private String password;
/**
* 部门id
*/
@NotNull(message = "部门不能为空")
private Long departmentId;
}

View File

@ -6,6 +6,7 @@ import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
@ -45,4 +46,16 @@ public class PrimaryAppUserAddRequest {
//职位id
private Integer titleId;
/**
* 部门id
*/
@NotNull(message = "部门不能为空")
private Long departmentId;
/**
* 地域类型字典id
*/
@NotNull(message = "地域类型不能为空")
private Integer regionTypeId;
}

View File

@ -6,6 +6,7 @@ import lombok.experimental.Accessors;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
@Data
@Accessors(chain = true)
@ -81,4 +82,6 @@ public class AdminUserVO {
*/
@JsonProperty("isGongfu")
private boolean isGongfu;
private List<AdminUserVO> children;
}

View File

@ -118,6 +118,16 @@ public class AppUserForAdminVO {
*/
private String customerName;
/**
* 部门id
*/
private Long departmentId;
/**
* 地域类型字典id
*/
private Integer regionTypeId;
//下级账号
private List<AppUserForAdminVO> children=new ArrayList<>();

View File

@ -1,6 +1,7 @@
package com.nflg.mobilebroken.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
@ -149,4 +150,15 @@ public class AppUser implements Serializable {
* 客户名称仅终端用户使用
*/
private String customerName;
/**
* 地域类型字典id
*/
@TableField("region_type_id")
private Integer regionTypeId;
/**
* 部门id
*/
private Long departmentId;
}

View File

@ -132,4 +132,9 @@ public class TBaseCustomer implements Serializable {
* 是否删除 0- 1-
*/
private Integer delIs;
/**
* 是否报价对象
*/
private Boolean quotationUse;
}

View File

@ -60,4 +60,6 @@ public interface IAdminUserService extends IService<AdminUser> {
List<AdminUser> getGongfuHandlers();
List<Integer> getGongfuTickerMangagers();
List<AdminUserVO> searchNew(SearchAccountRequest request);
}

View File

@ -1,6 +1,7 @@
package com.nflg.mobilebroken.repository.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -37,7 +38,6 @@ import java.util.stream.Collectors;
* <p>
* 后台-用户 服务实现类
* </p>
*
* @author 曹鹏飞
* @since 2025-01-03
*/
@ -418,4 +418,144 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
.one();
return Objects.nonNull(department) ? department.getDeptName() : "";
}
@Override
public List<AdminUserVO> searchNew(SearchAccountRequest request) {
List<TBaseDepartment> departments = departmentService.lambdaQuery()
.select(TBaseDepartment::getId, TBaseDepartment::getDeptName, TBaseDepartment::getDeptParentId)
.eq(TBaseDepartment::getDataValidStatus, 1)
.list();
List<TBasePosition> positions = positionService.list();
List<AdminUserRoleMap> roleMaps = adminUserRoleMapService.lambdaQuery().list();
List<AdminRole> roles = roleService.lambdaQuery().list();
if (Objects.nonNull(request.getDepartmentId())) {
TBaseDepartment department = departments.stream()
.filter(d -> Objects.equals(d.getId(), request.getDepartmentId()))
.findFirst()
.orElse(null);
if (Objects.isNull(department)) {
return Collections.emptyList();
}
List<AdminUser> adminUsers = lambdaQuery().eq(AdminUser::getIsDel, false).list();
List<AdminUser> roots = adminUsers.stream()
.filter(u -> Objects.equals(u.getDepartmentId(), department.getId()))
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(adminUsers)) {
return Collections.emptyList();
}
List<AdminUserVO> userVOS = convert(roots, department, positions, roleMaps, roles);
getChildren(userVOS.get(0), departments, adminUsers, positions, roleMaps, roles);
for (int index = 1, size = userVOS.size(); index < size; index++) {
userVOS.get(index).setChildren(userVOS.get(0).getChildren());
}
return userVOS;
} else {
List<AdminUser> adminUsers = lambdaQuery()
.eq(AdminUser::getIsDel, false)
.like(StrUtil.isNotBlank(request.getLoginName()), AdminUser::getLoginName, request.getLoginName())
.like(StrUtil.isNotBlank(request.getUserName()), AdminUser::getUserName, request.getUserName())
.eq(request.getState() != null, AdminUser::getState, request.getState())
.list();
if (CollectionUtil.isEmpty(adminUsers)) {
return Collections.emptyList();
}
List<AdminUserVO> userVOS = convert1(adminUsers, departments, positions, roleMaps, roles);
Set<TBaseDepartment> departmentVOS = departments.stream()
.filter(d -> userVOS.stream().map(AdminUserVO::getDepartmentId).anyMatch(dt -> Objects.equals(d.getId(), dt)))
.collect(Collectors.toSet());
departmentVOS.forEach(d -> bindParent(d, departmentVOS, departments));
List<TBaseDepartment> rootDepartments = departmentVOS.stream()
.filter(d -> d.getDeptParentId() == 0)
.collect(Collectors.toList());
// List<AdminUserVO>
// rootDepartments.forEach(d -> getChildren1(d, departmentVOS, adminUsers, positions, roleMaps, roles));
//TODO 绑定树形结构
return userVOS;
}
}
private void bindParent(TBaseDepartment department, Set<TBaseDepartment> vos, List<TBaseDepartment> departments) {
Set<TBaseDepartment> parents = departments.stream()
.filter(d -> Objects.equals(d.getId(), department.getDeptParentId()))
.collect(Collectors.toSet());
if (CollectionUtil.isNotEmpty(parents)) {
vos.addAll(parents);
parents.forEach(p -> bindParent(p, vos, departments));
}
}
private List<AdminUserVO> convert1(List<AdminUser> users, List<TBaseDepartment> departments, List<TBasePosition> positions
, List<AdminUserRoleMap> roleMaps, List<AdminRole> roles) {
return users.stream()
.map(user -> {
AdminUserVO vo = Convert.convert(AdminUserVO.class, user);
TBasePosition position = positions.stream()
.filter(p -> Objects.equals(p.getId(), user.getTitleId()))
.findFirst()
.orElse(null);
vo.setTitleName(Objects.nonNull(position) ? position.getPositionName() : "");
Set<Integer> rmaps = roleMaps.stream()
.filter(it -> Objects.equals(it.getUserId(), user.getId()))
.map(AdminUserRoleMap::getRoleId)
.collect(Collectors.toSet());
vo.setRoles(
roles.stream()
.filter(r -> rmaps.contains(r.getId()))
.map(r -> new RoleSimpleVO().setId(r.getId()).setName(r.getName()))
.collect(Collectors.toSet())
);
TBaseDepartment department = departments.stream()
.filter(d -> Objects.equals(d.getDeptParentId(), user.getDepartmentId()))
.findFirst()
.orElse(null);
vo.setDepartmentName(Objects.isNull(department) ? "" : department.getDeptName());
return vo;
}).collect(Collectors.toList());
}
private List<AdminUserVO> convert(List<AdminUser> users, TBaseDepartment department, List<TBasePosition> positions
, List<AdminUserRoleMap> roleMaps, List<AdminRole> roles) {
return users.stream()
.map(user -> {
AdminUserVO vo = Convert.convert(AdminUserVO.class, user);
TBasePosition position = positions.stream()
.filter(p -> Objects.equals(p.getId(), user.getTitleId()))
.findFirst()
.orElse(null);
vo.setTitleName(Objects.nonNull(position) ? position.getPositionName() : "");
Set<Integer> rmaps = roleMaps.stream()
.filter(it -> Objects.equals(it.getUserId(), user.getId()))
.map(AdminUserRoleMap::getRoleId)
.collect(Collectors.toSet());
vo.setRoles(
roles.stream()
.filter(r -> rmaps.contains(r.getId()))
.map(r -> new RoleSimpleVO().setId(r.getId()).setName(r.getName()))
.collect(Collectors.toSet())
);
vo.setDepartmentName(department.getDeptName());
return vo;
}).collect(Collectors.toList());
}
private void getChildren(AdminUserVO user, List<TBaseDepartment> departments, List<AdminUser> users
, List<TBasePosition> positions, List<AdminUserRoleMap> roleMaps, List<AdminRole> roles) {
TBaseDepartment department = departments.stream()
.filter(d -> Objects.equals(d.getDeptParentId(), user.getDepartmentId()))
.findFirst()
.orElse(null);
if (Objects.nonNull(department)) {
List<AdminUser> csers = users.stream()
.filter(u -> Objects.equals(u.getDepartmentId(), department.getId()))
.collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(csers)) {
List<AdminUserVO> cuserVOS = convert(csers, department, positions, roleMaps, roles);
user.setChildren(cuserVOS);
getChildren(cuserVOS.get(0), departments, users, positions, roleMaps, roles);
for (int index = 1, size = cuserVOS.size(); index < size; index++) {
cuserVOS.get(index).setChildren(cuserVOS.get(0).getChildren());
}
}
}
}
}

View File

@ -216,6 +216,8 @@ public class AppUserApplyforServiceImpl extends ServiceImpl<AppUserApplyforMappe
.setCompanyId(String.valueOf(applyfor.getCompanyId()))
.setTitleId(applyfor.getTitleId())
.setState(UserState.ToBeActivated.getState())
.setDepartmentId(request.getDepartmentId())
.setRegionTypeId(appUser.getRegionTypeId())
.setCreateBy(appUser.getName())
.setCreateTime(LocalDateTime.now())
.setExpireTime(appUser.getExpireTime())

View File

@ -172,6 +172,8 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> impl
.setSalesUserName(request.getSalesUserName())
.setUpdateBy(AdminUserUtil.getUserName())
.setUpdateTime(LocalDateTime.now())
.setDepartmentId(request.getDepartmentId())
.setRegionTypeId(request.getRegionTypeId())
.setState(UserState.ToBeActivated.getState())
.setExpireTime(LocalDate.of(LocalDateTime.now().getYear() + 1, 1, 1));
updateById(user);
@ -188,6 +190,8 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> impl
.setIsPrimary(true)
.setLanguageCode(request.getLanguageCode())
.setSalesUserName(request.getSalesUserName())
.setDepartmentId(request.getDepartmentId())
.setRegionTypeId(request.getRegionTypeId())
.setCreateBy(AdminUserUtil.getUserName())
.setCreateTime(LocalDateTime.now())
.setState(UserState.ToBeActivated.getState())

View File

@ -31,6 +31,7 @@
SELECT u.id,c.agency_company_name AS 'companyName',u.user_name AS 'name',u.user_email AS 'email',u.user_avatar AS 'avatar'
,a.`name` AS 'areaName',0 AS 'userState',u.create_by AS 'createBy',u.create_time AS 'createTime',u.update_by AS 'updateBy'
,u.update_time AS 'updateTime',null AS 'lastLoginTime',null AS 'expireTime',false AS 'isPrimary',0 AS 'state'
,u.user_type as 'type'
FROM app_user_applyfor u
INNER JOIN t_base_customer c ON u.company_id=c.id
INNER JOIN app_area a ON u.area_id=a.id
@ -122,7 +123,8 @@
,au.expire_time,IF(aua.id IS NOT NULL,0
,IF(CONVERT_TZ(NOW(), @@session.time_zone, '+00:00') &lt; au.expire_time,1,2)) AS 'state',au.create_by
,au.create_time,au.update_by,au.update_time,au.last_login_time,au.is_primary,au.company_id,au.phone,au.area_id
,au.language_code,p.position_name AS 'title',au.title_id,au.type,au.customer_name
,au.language_code,p.position_name AS
'title',au.title_id,au.type,au.customer_name,au.department_id,au.region_type_id
FROM app_user au
LEFT JOIN app_area aa ON au.area_id=aa.id
LEFT JOIN app_user_applyfor aua ON aua.user_id=au.id AND aua.state=0
@ -156,7 +158,8 @@
,IF(aua.is_primary,fun_getPrimaryUserArea(aua.company_id),aa.`name`) AS 'areaName'
,null AS 'userState',null AS 'expireTime',0 AS 'state',au.name AS 'createBy',aua.create_time,null AS 'updateBy'
,null AS 'updateTime',null AS 'lastLoginTime',aua.is_primary,aua.company_id,aua.user_phone AS 'phone',aua.area_id
,aua.language_code,p.position_name AS 'title',aua.title_id,au.type,au.customer_name
,aua.language_code,p.position_name AS
'title',aua.title_id,au.type,au.customer_name,au.department_id,au.region_type_id
FROM app_user_applyfor aua
LEFT JOIN app_user au ON au.id=aua.create_by
LEFT JOIN app_area aa ON aua.area_id=aa.id

View File

@ -18,6 +18,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;
@Slf4j
@Order(0)
@ -26,30 +27,39 @@ public class AppVersionFilter extends OncePerRequestFilter {
private static final ObjectMapper objectMapper = new ObjectMapper();
/**
* 因前端部分接口遗漏App-Version参数ios打包重新审核需要很久所以需要排除掉否则会导致接口无法访问
*/
private static final Set<String> WHITE_LIST = Set.of("getTicket", "uploadSingleFile", "getInfoById");
private static final String MIN_SUPPER_VERSION = "1.0.9";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
String appPlatform = request.getHeader("App-Platform");
response.setStatus(HttpServletResponse.SC_OK);
if (StrUtil.isBlank(appPlatform)) {
log.error("请求头中未找到App-Platform");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
out(response, ApiResult.error(STATE.ServiceConnectRefused, "请更新版本!"));
} else {
if (appPlatform.startsWith("pc")) {
filterChain.doFilter(request, response);
if (WHITE_LIST.stream().noneMatch(path -> request.getRequestURI().endsWith(path))) {
String appPlatform = request.getHeader("App-Platform");
response.setStatus(HttpServletResponse.SC_OK);
if (StrUtil.isBlank(appPlatform)) {
log.error("请求头中未找到App-Platform");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
out(response, ApiResult.error(STATE.ServiceConnectRefused, "请更新版本!"));
} else {
String appVersion = request.getHeader("App-Version");
if (StrUtil.isBlank(appVersion)) {
log.error("请求头中未找到App-Version");
out(response, ApiResult.error(STATE.ServiceConnectRefused, "请更新版本!"));
} else if (VersionComparator.INSTANCE.compare(appVersion, MIN_SUPPER_VERSION) < 0) {
out(response, ApiResult.error(STATE.ServiceConnectRefused, "版本太低,请更新版本!"));
} else {
if (appPlatform.startsWith("pc")) {
filterChain.doFilter(request, response);
} else {
String appVersion = request.getHeader("App-Version");
if (StrUtil.isBlank(appVersion)) {
log.error("请求头中未找到App-Version");
out(response, ApiResult.error(STATE.ServiceConnectRefused, "请更新版本!"));
} else if (VersionComparator.INSTANCE.compare(appVersion, MIN_SUPPER_VERSION) < 0) {
out(response, ApiResult.error(STATE.ServiceConnectRefused, "版本太低,请更新版本!"));
} else {
filterChain.doFilter(request, response);
}
}
}
} else {
filterChain.doFilter(request, response);
}
}