Commit 063658a3 by huangtao

角色展示

parent c096bf6e
...@@ -18,16 +18,16 @@ import static com.jmai.sys.service.UserService.KEY_ALL; ...@@ -18,16 +18,16 @@ import static com.jmai.sys.service.UserService.KEY_ALL;
@ApiModel(description = "用户信息") @ApiModel(description = "用户信息")
public class FullUserDto extends UserDto implements IDataPerms { public class FullUserDto extends UserDto implements IDataPerms {
@ApiModelProperty(value = "授权组织(编号)列表(逗号隔开)") @ApiModelProperty(value = "授权组织(编号)列表(逗号隔开)")
private String deptIdList; private String authDeptIdList;
@ApiModelProperty(value = "授权仓库/站点(名称)列表(逗号隔开)") @ApiModelProperty(value = "授权组织(名称)列表(逗号隔开)")
private String deptNameList; private String authDeptNameList;
@ApiModelProperty(value = "角色列表(逗号隔开)")
private String roleIdList;
@ApiModelProperty(value = "角色列表(逗号隔开)")
private String roleNameList;
@JsonIgnore
@JSONField(serialize = false)
public List<String> getDeptIdAsList() {
return extractStringList(deptIdList);
}
protected List<String> extractStringList(String input) { protected List<String> extractStringList(String input) {
if (ObjectUtil.equals(input, KEY_ALL)) { if (ObjectUtil.equals(input, KEY_ALL)) {
......
...@@ -33,12 +33,24 @@ public class UserDto extends BaseDto implements IStatus { ...@@ -33,12 +33,24 @@ public class UserDto extends BaseDto implements IStatus {
@ApiModelProperty(value = "状态:0 - 禁用,1 - 启用") @ApiModelProperty(value = "状态:0 - 禁用,1 - 启用")
private Integer status; private Integer status;
@ApiModelProperty(value = "组织(ID)")
private Long deptId;
@ApiModelProperty(value = "用户类型(角色)列表(逗号隔开)")
private String roleList;
@JsonIgnore @JsonIgnore
@JSONField(serialize = false) @JSONField(serialize = false)
public List<Long> getDeptAsList() { public List<Long> getAuthDeptAsList() {
return extractLongList(authDeptList); return extractLongList(authDeptList);
} }
@JsonIgnore
@JSONField(serialize = false)
public List<Long> getRoleAsList() {
return extractLongList(roleList);
}
/** /**
......
...@@ -41,6 +41,7 @@ import javax.annotation.Resource; ...@@ -41,6 +41,7 @@ import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
...@@ -119,20 +120,29 @@ public class UserServiceImpl extends AbstractService implements UserService { ...@@ -119,20 +120,29 @@ public class UserServiceImpl extends AbstractService implements UserService {
private List<FullUserDto> convertTo(List<SysUser> userList) { private List<FullUserDto> convertTo(List<SysUser> userList) {
List<FullUserDto> dtoList = convertTo(userList, this::convertToFullUser); List<FullUserDto> dtoList = convertTo(userList, this::convertToFullUser);
// 填充授权仓库名称 // 填充组织
List<Long> deptIdList = dtoList.stream() List<Long> deptIdList = dtoList.stream()
.flatMap(user -> user.getDeptAsList().stream()) .flatMap(user -> user.getAuthDeptAsList().stream())
.filter(ObjectUtil::isNotEmpty) .filter(ObjectUtil::isNotEmpty)
.distinct() .distinct()
.collect(Collectors.toList()); .collect(Collectors.toList());
Map<Long, DeptDto> deptMap = ObjectUtil.isEmpty(deptIdList) ? Map<Long, DeptDto> deptMap = ObjectUtil.isEmpty(deptIdList) ?
Collections.emptyMap() : Collections.emptyMap() :
deptService.getDeptMap(deptIdList); deptService.getDeptMap(deptIdList);
//填充角色
List<RoleTypeDTO> roles = getRoles();
Map<Long, RoleTypeDTO> roleMap = roles.stream().collect(Collectors.toMap(RoleTypeDTO::getId, Function.identity()));
dtoList.forEach(dto -> { dtoList.forEach(dto -> {
dto.setDeptIdList(extractDeptIdList(dto.getAuthDeptList(), deptMap)); dto.setAuthDeptIdList(extractDeptIdList(dto.getAuthDeptList(), deptMap));
dto.setDeptNameList(extractDeptNameList(dto.getAuthDeptList(), deptMap)); dto.setAuthDeptNameList(extractDeptNameList(dto.getAuthDeptList(), deptMap));
dto.setRoleIdList(extractRoleIdList(dto.getRoleList(), roleMap));
dto.setRoleNameList(extractRoleNameList(dto.getRoleList(), roleMap));
}); });
return dtoList; return dtoList;
} }
private String extractDeptIdList(String userDeptList, Map<Long, DeptDto> deptMap) { private String extractDeptIdList(String userDeptList, Map<Long, DeptDto> deptMap) {
...@@ -158,6 +168,55 @@ public class UserServiceImpl extends AbstractService implements UserService { ...@@ -158,6 +168,55 @@ public class UserServiceImpl extends AbstractService implements UserService {
.filter(StrUtil::isNotBlank) .filter(StrUtil::isNotBlank)
.collect(Collectors.joining(",")); .collect(Collectors.joining(","));
} }
private String extractRoleNameList(String roleList, Map<Long, RoleTypeDTO> roleMap) {
if (ObjectUtil.isEmpty(roleList)) {
// 无s授权住址
return "";
}
if (ObjectUtil.equals(roleList, KEY_ALL)) {
// 授权全部仓库
return KEY_NAME_ALL;
}
if (ObjectUtil.isEmpty(roleMap)) {
// 未找到仓库
return roleList;
}
return extractLongList(roleList)
.stream()
.filter(roleMap::containsKey)
.map(id -> {
RoleTypeDTO roleTypeDTO = roleMap.get(id);
return ObjectUtil.isEmpty(roleTypeDTO) ? "" : roleTypeDTO.getName();
})
.filter(StrUtil::isNotBlank)
.collect(Collectors.joining(","));
}
private String extractRoleIdList(String roleList, Map<Long, RoleTypeDTO> roleMap) {
if (ObjectUtil.isEmpty(roleList)) {
// 无s授权住址
return "";
}
if (ObjectUtil.equals(roleList, KEY_ALL)) {
// 授权全部仓库
return KEY_NAME_ALL;
}
if (ObjectUtil.isEmpty(roleMap)) {
// 未找到仓库
return roleList;
}
return extractLongList(roleList)
.stream()
.filter(roleMap::containsKey)
.map(id -> {
RoleTypeDTO roleTypeDTO = roleMap.get(id);
return ObjectUtil.isEmpty(roleTypeDTO) ? "" : roleTypeDTO.getId().toString();
})
.filter(StrUtil::isNotBlank)
.collect(Collectors.joining(","));
}
private String extractDeptNameList(String userDeptList, Map<Long, DeptDto> deptMap) { private String extractDeptNameList(String userDeptList, Map<Long, DeptDto> deptMap) {
if (ObjectUtil.isEmpty(userDeptList)) { if (ObjectUtil.isEmpty(userDeptList)) {
// 无s授权住址 // 无s授权住址
......
...@@ -4932,3 +4932,81 @@ Caused by: org.apache.ibatis.ognl.NoSuchPropertyException: com.jmai.physic.dto.P ...@@ -4932,3 +4932,81 @@ Caused by: org.apache.ibatis.ognl.NoSuchPropertyException: com.jmai.physic.dto.P
at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:46) at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:46)
... 96 common frames omitted ... 96 common frames omitted
[jmai:38098::] 2025-11-21 00:16:40.950[ERROR] 27752 [0cdd51e536ae4e49a24bf7e3a344674d] [http-nio-38098-exec-7:48920] [com.jmai.sys.exception.ServiceExceptionHandler.handleException:91] ServiceException:401 -- token失效,请重新登录。 -- {}
com.jmai.api.exception.ServiceException: 401,token失效,请重新登录。
at com.jmai.sys.aop.AuthAspect.checkTokenAndLoadContext(AuthAspect.java:114)
at com.jmai.sys.aop.AuthAspect.doBefore(AuthAspect.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:617)
at org.springframework.aop.aspectj.AspectJMethodBeforeAdvice.before(AspectJMethodBeforeAdvice.java:44)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:707)
at com.jmai.sys.controller.UserController$$EnhancerBySpringCGLIB$$14bdb032.listUsers(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:199)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144)
at com.jmai.sys.config.web.filter.TraceFilter.doFilter(TraceFilter.java:33)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:935)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1826)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.lang.Thread.run(Thread.java:750)
This diff could not be displayed because it is too large.
...@@ -897,3 +897,13 @@ ...@@ -897,3 +897,13 @@
1763609565139|78|statement|connection 0|INSERT INTO physic_bill ( id, dept_id, physic_name, physic_spec, batch_no, factory_name, type, expend_num, ref_id, status, balance, balance_all, version, del_flag, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )|INSERT INTO physic_bill ( id, dept_id, physic_name, physic_spec, batch_no, factory_name, type, expend_num, ref_id, status, balance, balance_all, version, del_flag, create_by, create_time, update_by, update_time ) VALUES ( 1991348963613605890, 1, '阿达帕林凝胶', '0.1%', '20250531', '武汉诺安药业有限公司', 2, 2, 1991095149795561474, 0, 3, 3, 1, 0, 1989173021538070529, '2025-11-20T11:32:45.057', 1989173021538070529, '2025-11-20T11:32:45.058' ) 1763609565139|78|statement|connection 0|INSERT INTO physic_bill ( id, dept_id, physic_name, physic_spec, batch_no, factory_name, type, expend_num, ref_id, status, balance, balance_all, version, del_flag, create_by, create_time, update_by, update_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )|INSERT INTO physic_bill ( id, dept_id, physic_name, physic_spec, batch_no, factory_name, type, expend_num, ref_id, status, balance, balance_all, version, del_flag, create_by, create_time, update_by, update_time ) VALUES ( 1991348963613605890, 1, '阿达帕林凝胶', '0.1%', '20250531', '武汉诺安药业有限公司', 2, 2, 1991095149795561474, 0, 3, 3, 1, 0, 1989173021538070529, '2025-11-20T11:32:45.057', 1989173021538070529, '2025-11-20T11:32:45.058' )
1763609565225|83|statement|connection 0|SELECT id,physic_name,physic_type,physic_spec,unit,return_num,prescription_num,requisition_num,actual_num,batch_no,factory_name,fy_dept_id,ly_dept_id,status,ly_user,sh_user,fy_user,fh_user,version,del_flag,create_by,create_time,update_by,update_time FROM physic_apply WHERE id=? AND del_flag=0|SELECT id,physic_name,physic_type,physic_spec,unit,return_num,prescription_num,requisition_num,actual_num,batch_no,factory_name,fy_dept_id,ly_dept_id,status,ly_user,sh_user,fy_user,fh_user,version,del_flag,create_by,create_time,update_by,update_time FROM physic_apply WHERE id=1991095149795561474 AND del_flag=0 1763609565225|83|statement|connection 0|SELECT id,physic_name,physic_type,physic_spec,unit,return_num,prescription_num,requisition_num,actual_num,batch_no,factory_name,fy_dept_id,ly_dept_id,status,ly_user,sh_user,fy_user,fh_user,version,del_flag,create_by,create_time,update_by,update_time FROM physic_apply WHERE id=? AND del_flag=0|SELECT id,physic_name,physic_type,physic_spec,unit,return_num,prescription_num,requisition_num,actual_num,batch_no,factory_name,fy_dept_id,ly_dept_id,status,ly_user,sh_user,fy_user,fh_user,version,del_flag,create_by,create_time,update_by,update_time FROM physic_apply WHERE id=1991095149795561474 AND del_flag=0
1763609565270|39|commit|connection 0|| 1763609565270|39|commit|connection 0||
1763655400931|42|statement|connection 0|SELECT id,token,refresh_token,user_id,expiry_time,version,del_flag,create_by,create_time,update_by,update_time FROM sys_user_token WHERE del_flag=0 AND (token = ?)|SELECT id,token,refresh_token,user_id,expiry_time,version,del_flag,create_by,create_time,update_by,update_time FROM sys_user_token WHERE del_flag=0 AND (token = '123')
1763655412110|34|statement|connection 0|SELECT id,token,refresh_token,user_id,expiry_time,version,del_flag,create_by,create_time,update_by,update_time FROM sys_user_token WHERE del_flag=0 AND (token = ?)|SELECT id,token,refresh_token,user_id,expiry_time,version,del_flag,create_by,create_time,update_by,update_time FROM sys_user_token WHERE del_flag=0 AND (token = '2df7822d-b449-4e64-a162-1765bc43a3cd')
1763655412154|34|statement|connection 0|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE id=? AND del_flag=0|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE id=1000 AND del_flag=0
1763655412240|35|statement|connection 0|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE del_flag=0 AND (id = ? AND type = ? AND type <> ? AND status = ?)|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE del_flag=0 AND (id = 0 AND type = 0 AND type <> 0 AND status = 0)
1763655443920|33|statement|connection 0|SELECT id,token,refresh_token,user_id,expiry_time,version,del_flag,create_by,create_time,update_by,update_time FROM sys_user_token WHERE del_flag=0 AND (token = ?)|SELECT id,token,refresh_token,user_id,expiry_time,version,del_flag,create_by,create_time,update_by,update_time FROM sys_user_token WHERE del_flag=0 AND (token = '2df7822d-b449-4e64-a162-1765bc43a3cd')
1763655443957|33|statement|connection 0|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE id=? AND del_flag=0|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE id=1000 AND del_flag=0
1763655461161|33|statement|connection 0|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE del_flag=0 AND (id = ? AND type = ? AND type <> ? AND status = ?)|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE del_flag=0 AND (id = 0 AND type = 0 AND type <> 0 AND status = 0)
1763655490923|44|statement|connection 0|SELECT id,token,refresh_token,user_id,expiry_time,version,del_flag,create_by,create_time,update_by,update_time FROM sys_user_token WHERE del_flag=0 AND (token = ?)|SELECT id,token,refresh_token,user_id,expiry_time,version,del_flag,create_by,create_time,update_by,update_time FROM sys_user_token WHERE del_flag=0 AND (token = '2df7822d-b449-4e64-a162-1765bc43a3cd')
1763655490968|40|statement|connection 0|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE id=? AND del_flag=0|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE id=1000 AND del_flag=0
1763655494549|35|statement|connection 0|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE del_flag=0 AND (type <> ?)|SELECT id,name,mobile,salt,password,type,auth_dept_list,dept_id,role_list,status,ext,del_flag,create_by,create_time,update_by,update_time FROM sys_user WHERE del_flag=0 AND (type <> 0)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment