Commit 15d17512 authored by fangxinjiang's avatar fangxinjiang

B端服务添加:客户&项目接口改造

parent eb9b9252
package com.yifu.cloud.plus.v1.yifu.archives.vo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TCustomerInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TSettleDomain;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
......@@ -24,11 +25,10 @@ public class CustomerForBusinessVo {
private List<String> hadSettle;
//客户分页信息
/* @Schema(name = "客户分页信息")
Page<TCustomerInfo> customerInfoPage;
Page<TCustomerInfo> customerInfoPage;*/
//结算主体
@Schema(name = "客户信息")
private List<TCustomerInfo> customerList;*/
private List<TCustomerInfo> customerList;
//结算主体
@Schema(name = "结算主体")
......
......@@ -16,6 +16,7 @@ import com.yifu.cloud.plus.v1.yifu.archives.utils.ListWrapper;
import com.yifu.cloud.plus.v1.yifu.archives.vo.CustomerForBusinessVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.CustomerOwnerSelectVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CacheConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.EmpBusinessConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ServiceNameConstants;
......@@ -29,13 +30,11 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
......@@ -61,6 +60,8 @@ public class CustomerBusinessContoller {
private final RedisUtil redisUtil;
private final UpmsDaprUtils upmsDaprUtils;
private final CacheManager cacheManager;
/**
* 简单分页查询
* @param page 分页对象
......@@ -74,7 +75,7 @@ public class CustomerBusinessContoller {
tCustomerInfo.setCustomerIds(Common.initStrToList(customerIdStr,CommonConstants.COMMA_STRING));
}
page.addOrder(OrderItem.desc(CREATE_TIME_COLNUM));
return null; // TODO new R<>(tCustomerInfoService.getTCustomerInfoPageForB(page,tCustomerInfo));
return tSettleDomainService.getTCustomerInfoPageForB(page,tCustomerInfo);
}
/**
......@@ -99,7 +100,7 @@ public class CustomerBusinessContoller {
List<String> settleDomainIds;
boolean flag = !SecurityUtils.isHaveAllOrg(ServiceNameConstants.CLIENT_ID_HR_B, user);
if (flag) {
settleDomainIds = null;// TODO user.getSettleIdList();
settleDomainIds = user.getSettleIdList();
if (Common.isEmpty(settleDomainIds)) {
return R.failed(EmpBusinessConstants.noSettleDomainAuth);
}
......@@ -107,7 +108,7 @@ public class CustomerBusinessContoller {
}
}
page.addOrder(OrderItem.desc("CREATE_TIME"));
return null;// TODO new R(tSettleDomainService.getTSettleDomainPageB(page, tSettleDomain));
return tSettleDomainService.getTSettleDomainPageB(page, tSettleDomain);
}
/**
* 获取客户下的结算主体(未删除、不是审核不通过的)
......@@ -118,6 +119,7 @@ public class CustomerBusinessContoller {
public R<List<TSettleDomain>> getSettleDomain(@PathVariable String customerId) {
return new R<>(tSettleDomainService.list(getSettleDomainWrapper(CollUtil.toList(customerId))));
}
/**
* 保存客户结算主体关系
*/
......@@ -140,6 +142,8 @@ public class CustomerBusinessContoller {
log.info("清除b端结算主体缓存: "+ ServiceNameConstants.UMPS_SERVICE + "_user_details_phone::" + user.getPhone());
redisUtil.remove(ServiceNameConstants.UMPS_SERVICE + "_user_details_phone::" + user.getPhone());
}
// 清空userinfo
Objects.requireNonNull(cacheManager.getCache(CacheConstants.USER_DETAILS)).clear();
}
return R.ok();
}else {
......@@ -177,8 +181,8 @@ public class CustomerBusinessContoller {
}
result.setHadSettle(setttleList);
result.setHadCustomer(customerList);
// 获取所有有权限的客户信息 TODO
//result.setCustomerList(tCustomerInfoService.list(Wrappers.<TCustomerInfo>query().lambda().in(TCustomerInfo::getId,customerList)));
// 获取所有有权限的客户信息
result.setCustomerList(tSettleDomainService.getTCustomerInfoForB(customerList));
//获取该客户下的主体
result.setSettleDomainList(tSettleDomainService.list(getSettleDomainWrapper(customerList)));
}
......@@ -260,6 +264,13 @@ public class CustomerBusinessContoller {
@Operation(description = "获取权限内所有客户下拉项")
@GetMapping("/getCustomerOwnerPage")
public R<IPage<CustomerOwnerSelectVo> > getCustomerOwnerPage(Page<CustomerOwnerSelectVo> page, String customerName) {
return null;// TODO tSettleDomainService.getCustomerOwnerPage(page,customerName);
YifuUser user = SecurityUtils.getUser();
if(null == user){
return R.failed("非法用户!");
}
if (Common.isEmpty(user.getSettleIdList())){
return R.ok();
}
return tSettleDomainService.getCustomerOwnerPage(page,customerName,user.getSettleIdList());
}
}
......@@ -160,6 +160,23 @@ public class TSettleDomainController {
return vo;
}
/**
* 获取登录用户拥有的项目信息及单位部分信息
*
* @param
* @return
* @Author fxj
* @Date 2019-08-28
**/
@Operation(description = "获取登录用户拥有的项目数据)")
@Inner
@PostMapping("/getPermissionByUserId")
public TSettleDomainListVo getPermissionByUserId(@RequestBody String userId) {
TSettleDomainListVo vo = new TSettleDomainListVo();
vo.setDeptIds(tSettleDomainService.getSettleDomainIdsByUserId(userId));
return vo;
}
/**
* @param
* @Author: wangan
......
......@@ -20,11 +20,10 @@ package com.yifu.cloud.plus.v1.yifu.archives.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TCustomerInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TSettleDomain;
import com.yifu.cloud.plus.v1.yifu.archives.vo.IdNameNoVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.ProjectSetInfoVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainSelectVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
......@@ -83,4 +82,14 @@ public interface TSettleDomainMapper extends BaseMapper<TSettleDomain> {
List<TSettleDomain> getOwnSettleDomainNoPage(@Param("userId") String userId, @Param("name") String name);
IPage<TSettleDomainVo> getOwnSettleDomain(Page page, @Param("userId") String userId, @Param("name") String name);
IPage<TCustomerInfo> getTCustomerInfoPageForB(Page page, @Param("tSettleDomain")TCustomerInfo tSettleDomain);
IPage<TSettleDomainVo> getTSettleDomainPageB(Page page, @Param("tSettleDomain")TSettleDomainVo tSettleDomain);
List<TCustomerInfo> getTCustomerInfoForB(@Param("tSettleDomain")List<String> tSettleDomain);
IPage<CustomerOwnerSelectVo> getCustomerOwnerPage(Page page,
@Param("customerName")String customerName,
@Param("settleIdList")List<String> settleIdList);
}
......@@ -20,6 +20,7 @@ package com.yifu.cloud.plus.v1.yifu.archives.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TCustomerInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TSettleDomain;
import com.yifu.cloud.plus.v1.yifu.archives.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
......@@ -113,4 +114,12 @@ public interface TSettleDomainService extends IService<TSettleDomain> {
List<TSettleDomain> getOwnSettleDomainNoPage(String toString, String settleName);
R<IPage<TSettleDomainVo>> getOwnSettleDomain(Page<TSettleDomainVo> page, String userId, String name);
R<IPage<TCustomerInfo>> getTCustomerInfoPageForB(Page<TCustomerInfo> page, TCustomerInfo tCustomerInfo);
R<IPage<TSettleDomainVo>> getTSettleDomainPageB(Page<TSettleDomainVo> page, TSettleDomainVo tSettleDomain);
List<TCustomerInfo> getTCustomerInfoForB(List<String> customerList);
R<IPage<CustomerOwnerSelectVo>> getCustomerOwnerPage(Page<CustomerOwnerSelectVo> page, String customerName, List<String> settleIdList);
}
......@@ -25,6 +25,7 @@ import com.yifu.cloud.plus.v1.yifu.admin.api.entity.SysUser;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.AreaMap;
import com.yifu.cloud.plus.v1.yifu.admin.api.vo.SysUserListVo;
import com.yifu.cloud.plus.v1.yifu.archives.constants.ArchivesConstants;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TCustomerInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TCutsomerDataPermisson;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TSettleDomain;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TCutsomerDataPermissonMapper;
......@@ -41,14 +42,12 @@ import com.yifu.cloud.plus.v1.yifu.common.dapr.util.UpmsDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.mybatis.base.BaseEntity;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
......@@ -82,7 +81,7 @@ public class TSettleDomainServiceImpl extends ServiceImpl<TSettleDomainMapper, T
public IPage<IdNameNoVo> getUnitPage(Page<IdNameNoVo> page, IdNameNoVo idNameNoVo) {
return baseMapper.getUnitPage(page, idNameNoVo);
}
private final CacheManager cacheManager;
/**
* @Author fxj
* @Description 清除项目缓存
......@@ -95,6 +94,12 @@ public class TSettleDomainServiceImpl extends ServiceImpl<TSettleDomainMapper, T
try{
for(String userId : userIdList){
redisUtil.remove(CacheConstants.WXHR_SETTLE_DOMAIN_VOS_BY_USERID +"_"+userId);
// 清空userinfo
Objects.requireNonNull(cacheManager.getCache(CacheConstants.USER_DETAILS)).clear();
redisUtil.remove(CacheConstants.USER_DETAILS +"::"+ user.getUsername());
if( Common.isNotNull(user.getPhone())){
redisUtil.remove(CacheConstants.USER_DETAILS + "_phone::"+ user.getPhone());
}
}
} catch (Exception e) {
log.error("清除缓存错误:",e);
......@@ -442,4 +447,28 @@ public class TSettleDomainServiceImpl extends ServiceImpl<TSettleDomainMapper, T
}
return (R<IPage<TSettleDomainVo>>) Collections.emptyList();
}
@Override
public R<IPage<TCustomerInfo>> getTCustomerInfoPageForB(Page<TCustomerInfo> page, TCustomerInfo tCustomerInfo) {
return R.ok(baseMapper.getTCustomerInfoPageForB(page,tCustomerInfo));
}
@Override
public R<IPage<TSettleDomainVo>> getTSettleDomainPageB(Page<TSettleDomainVo> page, TSettleDomainVo tSettleDomain) {
return R.ok(baseMapper.getTSettleDomainPageB(page,tSettleDomain));
}
@Override
public List<TCustomerInfo> getTCustomerInfoForB(List<String> customerList) {
if (Common.isNotNull(customerList)){
return baseMapper.getTCustomerInfoForB(customerList);
}
return null;
}
@Override
public R<IPage<CustomerOwnerSelectVo>> getCustomerOwnerPage(Page<CustomerOwnerSelectVo> page, String customerName,
List<String> settleIdList) {
return R.ok(baseMapper.getCustomerOwnerPage(page,customerName,settleIdList));
}
}
......@@ -340,4 +340,94 @@
</if>
and a.id in (select b.settle_id from m_setttle_customer_user b where b.user_id = #{userId}) and a.DELETE_FLAG = '0'
</select>
<select id="getTCustomerInfoPageForB" resultType="com.yifu.cloud.plus.v1.yifu.archives.entity.TCustomerInfo">
SELECT
a.CUSTOMER_ID AS 'id',
a.CUSTOMER_NAME as 'customerName',
a.CUSTOMER_NO as 'customerCode'
FROM t_settle_domain a
WHERE a.DELETE_FLAG='0'
<if test="tSettleDomain != null">
<if test="tSettleDomain.customerName != null and tSettleDomain.customerName.trim() != ''">
and a.CUSTOMER_NAME like concat('%', #{tSettleDomain.customerName} ,'%')
</if>
<if test="tSettleDomain.customerCode != null and tSettleDomain.customerCode.trim() != ''">
and a.CUSTOMER_CODE = #{tSettleDomain.customerCode}
</if>
<if test="tSettleDomain.customerIds != null and tSettleDomain.customerIds.size() > 0">
and a.CUSTOMER_ID in
<foreach collection="tSettleDomain.customerIds" item="param" index="index" open="(" close=")" separator=",">
#{param}
</foreach>
</if>
</if>
group by a.CUSTOMER_CODE order by CREATE_TIME desc
</select>
<select id="getTSettleDomainPageB" resultMap="tSettleDomainMap">
SELECT
<include refid="Base_Column_List"/>
FROM
t_settle_domain a
where
1=1
<if test="tSettleDomain.customerName != null and tSettleDomain.customerName.trim() != ''">
AND a.CUSTOMER_NAME like CONCAT('%',#{tSettleDomain.customerName,jdbcType=VARCHAR},'%')
</if>
<if test="tSettleDomain.customerCode != null and tSettleDomain.customerCode.trim() != ''">
AND a.CUSTOMER_CODE like CONCAT('%',#{tSettleDomain.customerCode,jdbcType=VARCHAR},'%')
</if>
<if test="tSettleDomain.departNo != null and tSettleDomain.departNo.trim() != ''">
AND a.DEPART_NO like CONCAT('%',#{tSettleDomain.departNo,jdbcType=VARCHAR},'%')
</if>
<if test="tSettleDomain.departName != null and tSettleDomain.departName.trim() != ''">
AND a.DEPART_NAME like CONCAT('%',#{tSettleDomain.departName,jdbcType=VARCHAR},'%')
</if>
<if test="tSettleDomain.settleDomainIds != null and tSettleDomain.settleDomainIds.size >0">
AND a.id in
<foreach item="item" index="index" collection="tSettleDomain.settleDomainIds" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</select>
<select id="getTCustomerInfoForB" resultType="com.yifu.cloud.plus.v1.yifu.archives.entity.TCustomerInfo">
SELECT
a.CUSTOMER_ID AS 'id',
a.CUSTOMER_NAME as 'customerName',
a.CUSTOMER_NO as 'customerCode'
FROM t_settle_domain a
WHERE a.DELETE_FLAG='0'
<if test="tSettleDomain != null">
<if test="tSettleDomain.customerIds != null and tSettleDomain.customerIds.size() > 0">
and a.CUSTOMER_ID in
<foreach collection="tSettleDomain.customerIds" item="param" index="index" open="(" close=")" separator=",">
#{param}
</foreach>
</if>
</if>
group by a.CUSTOMER_CODE order by CREATE_TIME desc
</select>
<select id="getCustomerOwnerPage" resultType="com.yifu.cloud.plus.v1.yifu.archives.vo.CustomerOwnerSelectVo">
SELECT
a.CUSTOMER_ID AS 'customerId',
a.CUSTOMER_NAME as 'customerName',
a.CUSTOMER_NO as 'customerCode'
FROM
t_settle_domain a
where
1=1
<if test="customerName != null and customerName.trim() != ''">
AND a.CUSTOMER_NAME like CONCAT('%',#{customerName},'%')
</if>
<if test="settleIdList != null and settleIdList.size >0">
AND a.id in
<foreach item="item" index="index" collection="settleIdList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
group by a.CUSTOMER_CODE order by CREATE_TIME desc
</select>
</mapper>
......@@ -115,7 +115,8 @@ public class YifuTokenEndpoint {
user.getNickname(),user.getSystemFlag(), SecurityConstants.BCRYPT + user.getPassword(),
user.getPhone(), true, true, true,
CommonConstants.STATUS_NORMAL.equals(user.getLockFlag()),
user.getUserGroup(),authorities, user.getLdapDn(), info.getClientRoleMap());
user.getUserGroup(),authorities, user.getLdapDn(),
info.getClientRoleMap(),info.getSettleIdList());
thisUser.setClientRoleMap(info.getClientRoleMap());
return thisUser;
}
......
......@@ -84,12 +84,21 @@ public class YifuUser extends User {
*/
@Getter
private String ldapDn;
/**
* @Author fxj
* @Description 人员项目权限
* @Date 13:53 2023/1/3
**/
@Getter
@Setter
private List<String> settleIdList;
public YifuUser(String id, Long deptId,String deptName, String username, String nickname,String systemFlag,
String password, String phone, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked,
String userGroup, Collection<? extends GrantedAuthority> authorities, String ldapDn,
Map<String, List<Long>> clientRoleMap) {
Map<String, List<Long>> clientRoleMap,
List<String> settleIdList) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
this.id = id;
this.deptId = deptId;
......@@ -100,5 +109,6 @@ public class YifuUser extends User {
this.userGroup = userGroup;
this.ldapDn = ldapDn;
this.clientRoleMap=clientRoleMap;
this.settleIdList=settleIdList;
}
}
......@@ -381,4 +381,19 @@ public class ArchivesDaprUtil {
}
return res;
}
/**
* @Author fxj
* @Description 获取所有客户单位的项目信息
* @Date 21:18 2022/7/18
* @Param
* @return
**/
public R<TSettleDomainListVo> getPermissionByUserId(String userId){
R<TSettleDomainListVo> res = HttpDaprUtil.invokeMethodPost(daprArchivesProperties.getAppUrl(),daprArchivesProperties.getAppId(),"/tsettledomain/getPermissionByUserId",userId, TSettleDomainListVo.class, SecurityConstants.FROM_IN);
if (Common.isEmpty(res)){
return R.failed("获取所有客户单位的项目信息失败!");
}
return res;
}
}
......@@ -73,7 +73,7 @@ public interface YifuUserDetailsService extends UserDetailsService, Ordered {
user.getNickname(),user.getSystemFlag(), SecurityConstants.BCRYPT + user.getPassword(),
user.getPhone(), true, true, true,
StrUtil.equals(user.getLockFlag(), CommonConstants.STATUS_NORMAL),
user.getUserGroup(),authorities, user.getLdapDn(),info.getClientRoleMap());
user.getUserGroup(),authorities, user.getLdapDn(),info.getClientRoleMap(),info.getSettleIdList());
}
/**
......
......@@ -69,4 +69,11 @@ public class UserInfo implements Serializable {
* key是客户端id,val是角色id数组
*/
private Map<String,List<Long>> clientRoleMap;
/**
* @Author fxj
* @Description 人员项目权限
* @Date 13:53 2023/1/3
**/
private List<String> settleIdList;
}
......@@ -37,15 +37,16 @@ import com.yifu.cloud.plus.v1.yifu.admin.api.vo.UserVO;
import com.yifu.cloud.plus.v1.yifu.admin.mapper.*;
import com.yifu.cloud.plus.v1.yifu.admin.service.SysMenuService;
import com.yifu.cloud.plus.v1.yifu.admin.service.SysUserService;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainListVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CacheConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ServiceNameConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.enums.MenuTypeEnum;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.ErrorCodes;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.MsgUtils;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.util.RedisUtil;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.ArchivesDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.ldap.entity.PersonVo;
import com.yifu.cloud.plus.v1.yifu.common.ldap.util.LdapUtil;
import lombok.RequiredArgsConstructor;
......@@ -92,6 +93,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
private final RedisUtil redisUtil;
private final ArchivesDaprUtil archivesDaprUtil;
/**
* 保存用户信息
* @param userDto DTO 对象
......@@ -152,29 +155,20 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
Map<String, List<Long>> clientRoleMap = new HashMap<>();
if (Common.isNotNull(roles)){
roles.forEach(role -> {
if (null != clientRoleMap.get(role.getClientId())) {
clientRoleMap.get(role.getClientId()).add(role.getRoleId());
} else {
clientRoleMap.put(role.getClientId(), Stream.of(role.getRoleId()).collect(toList()));
}
/* List<String> permissionList = sysMenuService.findMenuByRoleId(role.getRoleId())
.stream()
.filter(menuVo -> Common.isNotNull(menuVo.getPermission()))
.map(menuVo -> {
if (menuVo.getPermission().contains(":")) {
return menuVo.getPermission();
} else {
return role.getClientId() + ":" + menuVo.getPermission();
}
})
.collect(toList());
permissions.addAll(permissionList);*/
}
);
}
// 结算主体权限
R< TSettleDomainListVo > sdRes = archivesDaprUtil.getPermissionByUserId(sysUser.getUserId());
if (Common.isNotNull(sdRes) && Common.isNotNull(sdRes.getData())){
userInfo.setSettleIdList(sdRes.getData().getDeptIds());
}
userInfo.setClientRoleMap(clientRoleMap);
return userInfo;
}
......
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 to comment