u
This commit is contained in:
1 parent
2f8a815c62
commit
c76581d8cb
34 files changed
+539
-277
No files matched your search
+23
-8
@@ -5,17 +5,32 @@ import lombok.Data;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
public class AuthLoginVO {
|
public class AuthLoginVO {
|
||||||
private Long companyId;
|
|
||||||
private String companyLogo;
|
|
||||||
private String companyName;
|
|
||||||
|
|
||||||
private Long userId;
|
private Company company;
|
||||||
private Integer userRole;
|
private User user;
|
||||||
private String userName;
|
|
||||||
private String userPosition;
|
|
||||||
|
|
||||||
private String token;
|
private String token;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class Company {
|
||||||
|
private Long id;
|
||||||
|
private String logo;
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class User {
|
||||||
|
private Long id;
|
||||||
|
private Integer role;
|
||||||
|
private String name;
|
||||||
|
private String position;
|
||||||
|
private String avatar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+16
-12
@@ -9,8 +9,8 @@ import cn.link56.auth.identity.model.vo.AuthLoginVO;
|
|||||||
import cn.link56.auth.token.model.AuthToken;
|
import cn.link56.auth.token.model.AuthToken;
|
||||||
import cn.link56.auth.token.model.TokenPayload;
|
import cn.link56.auth.token.model.TokenPayload;
|
||||||
import cn.link56.auth.token.service.AuthTokenService;
|
import cn.link56.auth.token.service.AuthTokenService;
|
||||||
import cn.link56.company.model.po.CompanyPO;
|
import cn.link56.company.model.po.Company;
|
||||||
import cn.link56.company.model.po.CompanyUserPO;
|
import cn.link56.company.model.po.CompanyUser;
|
||||||
import cn.link56.auth.identity.model.dto.AuthRegisterDTO;
|
import cn.link56.auth.identity.model.dto.AuthRegisterDTO;
|
||||||
import cn.link56.company.service.CompanyService;
|
import cn.link56.company.service.CompanyService;
|
||||||
import cn.link56.company.service.CompanyUserService;
|
import cn.link56.company.service.CompanyUserService;
|
||||||
@@ -61,7 +61,7 @@ public class AuthIdentityService {
|
|||||||
long companyId = IdGenerator.nextId();
|
long companyId = IdGenerator.nextId();
|
||||||
|
|
||||||
companyService.save(
|
companyService.save(
|
||||||
new CompanyPO()
|
new Company()
|
||||||
.setId(companyId)
|
.setId(companyId)
|
||||||
.setName(company.getName())
|
.setName(company.getName())
|
||||||
.setIndustry(StringUtils.join(company.getIndustries(),","))
|
.setIndustry(StringUtils.join(company.getIndustries(),","))
|
||||||
@@ -72,7 +72,7 @@ public class AuthIdentityService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
companyUserService.save(
|
companyUserService.save(
|
||||||
new CompanyUserPO()
|
new CompanyUser()
|
||||||
.setId(IdGenerator.nextId())
|
.setId(IdGenerator.nextId())
|
||||||
.setCompanyId(companyId)
|
.setCompanyId(companyId)
|
||||||
.setName(admin.getName())
|
.setName(admin.getName())
|
||||||
@@ -85,7 +85,7 @@ public class AuthIdentityService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public AuthLoginVO loginByPassword(AuthLoginPasswordDTO dto) {
|
public AuthLoginVO loginByPassword(AuthLoginPasswordDTO dto) {
|
||||||
CompanyUserPO user = companyUserService.loginByEmailAndPassword(dto.getEmail(), dto.getPassword());
|
CompanyUser user = companyUserService.loginByEmailAndPassword(dto.getEmail(), dto.getPassword());
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new BusinessException("邮箱或密码错误");
|
throw new BusinessException("邮箱或密码错误");
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ public class AuthIdentityService {
|
|||||||
throw new BusinessException("邮箱或验证码失效");
|
throw new BusinessException("邮箱或验证码失效");
|
||||||
}
|
}
|
||||||
|
|
||||||
CompanyUserPO user = companyUserService.loginByEmail(email);
|
CompanyUser user = companyUserService.loginByEmail(email);
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new BusinessException("邮箱不存在");
|
throw new BusinessException("邮箱不存在");
|
||||||
}
|
}
|
||||||
@@ -118,8 +118,8 @@ public class AuthIdentityService {
|
|||||||
/**
|
/**
|
||||||
* 公共逻辑:根据用户生成 LoginVO
|
* 公共逻辑:根据用户生成 LoginVO
|
||||||
*/
|
*/
|
||||||
private AuthLoginVO buildLoginVO(CompanyUserPO user) {
|
private AuthLoginVO buildLoginVO(CompanyUser user) {
|
||||||
CompanyPO company = companyService.getById(user.getCompanyId());
|
Company company = companyService.getById(user.getCompanyId());
|
||||||
|
|
||||||
TokenPayload tokenPayload = new TokenPayload();
|
TokenPayload tokenPayload = new TokenPayload();
|
||||||
tokenPayload.setCompanyId(user.getCompanyId());
|
tokenPayload.setCompanyId(user.getCompanyId());
|
||||||
@@ -127,18 +127,22 @@ public class AuthIdentityService {
|
|||||||
|
|
||||||
AuthToken authToken = tokenService.generateToken(tokenPayload);
|
AuthToken authToken = tokenService.generateToken(tokenPayload);
|
||||||
|
|
||||||
return new AuthLoginVO(
|
AuthLoginVO.Company companyVO = new AuthLoginVO.Company(
|
||||||
company.getId(),
|
company.getId(),
|
||||||
company.getLogo(),
|
company.getLogo(),
|
||||||
company.getName(),
|
company.getName()
|
||||||
|
);
|
||||||
|
|
||||||
|
AuthLoginVO.User userVO = new AuthLoginVO.User(
|
||||||
user.getId(),
|
user.getId(),
|
||||||
user.getRole(),
|
user.getRole(),
|
||||||
user.getName(),
|
user.getName(),
|
||||||
user.getPosition(),
|
user.getPosition(),
|
||||||
|
user.getAvatar()
|
||||||
authToken.getToken()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return new AuthLoginVO(companyVO, userVO, authToken.getToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,13 +1,13 @@
|
|||||||
package cn.link56.company.mapper;
|
package cn.link56.company.mapper;
|
||||||
|
|
||||||
import cn.link56.company.model.middle.RecommendCompanyRow;
|
import cn.link56.company.model.middle.RecommendCompanyRow;
|
||||||
import cn.link56.company.model.po.CompanyPO;
|
import cn.link56.company.model.po.Company;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface CompanyMapper extends BaseMapper<CompanyPO> {
|
public interface CompanyMapper extends BaseMapper<Company> {
|
||||||
List<RecommendCompanyRow> listRecommend();
|
List<RecommendCompanyRow> listRecommend();
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
package cn.link56.company.mapper;
|
package cn.link56.company.mapper;
|
||||||
|
|
||||||
import cn.link56.company.model.po.CompanyUserPO;
|
import cn.link56.company.model.po.CompanyUser;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface CompanyUserMapper extends BaseMapper<CompanyUserPO> {
|
public interface CompanyUserMapper extends BaseMapper<CompanyUser> {
|
||||||
}
|
}
|
||||||
+2
@@ -24,4 +24,6 @@ public class UpdateCompanyUserDTO {
|
|||||||
private String name;
|
private String name;
|
||||||
private String phone;
|
private String phone;
|
||||||
private String canuse;
|
private String canuse;
|
||||||
|
|
||||||
|
private String avatar;
|
||||||
}
|
}
|
||||||
+1
-1
@@ -17,7 +17,7 @@ import java.util.Date;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@TableName("b_company")
|
@TableName("b_company")
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class CompanyPO {
|
public class Company {
|
||||||
@TableId(value = "b_id")
|
@TableId(value = "b_id")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
+4
-1
@@ -17,7 +17,7 @@ import java.util.Date;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@TableName("b_company_user")
|
@TableName("b_company_user")
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class CompanyUserPO {
|
public class CompanyUser {
|
||||||
@TableId(value = "b_id")
|
@TableId(value = "b_id")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@@ -42,6 +42,9 @@ public class CompanyUserPO {
|
|||||||
@TableField("b_position")
|
@TableField("b_position")
|
||||||
private String position;
|
private String position;
|
||||||
|
|
||||||
|
@TableField("b_avatar")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
@TableField("b_canuse")
|
@TableField("b_canuse")
|
||||||
private String canuse;
|
private String canuse;
|
||||||
|
|
||||||
+2
-1
@@ -26,7 +26,7 @@ public class CompanyDetailVO {
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public static class User{
|
public static class User {
|
||||||
private Long id;
|
private Long id;
|
||||||
private Long companyId;
|
private Long companyId;
|
||||||
private String email;
|
private String email;
|
||||||
@@ -34,5 +34,6 @@ public class CompanyDetailVO {
|
|||||||
private Integer role;
|
private Integer role;
|
||||||
private String position;
|
private String position;
|
||||||
private String name;
|
private String name;
|
||||||
|
private String avatar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
@@ -17,5 +17,7 @@ public class QueryCompanyUserVO {
|
|||||||
private String email;
|
private String email;
|
||||||
private String phone;
|
private String phone;
|
||||||
|
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
private String canuse;
|
private String canuse;
|
||||||
}
|
}
|
||||||
+36
-37
@@ -7,8 +7,8 @@ import cn.link56.company.mapper.CompanyMapper;
|
|||||||
import cn.link56.company.model.dto.QueryCompanyDTO;
|
import cn.link56.company.model.dto.QueryCompanyDTO;
|
||||||
import cn.link56.company.model.dto.UpdateCompanyDTO;
|
import cn.link56.company.model.dto.UpdateCompanyDTO;
|
||||||
import cn.link56.company.model.middle.RecommendCompanyRow;
|
import cn.link56.company.model.middle.RecommendCompanyRow;
|
||||||
import cn.link56.company.model.po.CompanyPO;
|
import cn.link56.company.model.po.Company;
|
||||||
import cn.link56.company.model.po.CompanyUserPO;
|
import cn.link56.company.model.po.CompanyUser;
|
||||||
import cn.link56.company.model.vo.CompanyDetailVO;
|
import cn.link56.company.model.vo.CompanyDetailVO;
|
||||||
import cn.link56.company.model.vo.QueryCompanyVO;
|
import cn.link56.company.model.vo.QueryCompanyVO;
|
||||||
import cn.link56.company.model.vo.RecommendCompanyVO;
|
import cn.link56.company.model.vo.RecommendCompanyVO;
|
||||||
@@ -29,7 +29,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class CompanyService extends ServiceImpl<CompanyMapper,CompanyPO> {
|
public class CompanyService extends ServiceImpl<CompanyMapper, Company> {
|
||||||
@Resource
|
@Resource
|
||||||
private CompanyMapper companyMapper;
|
private CompanyMapper companyMapper;
|
||||||
@Resource
|
@Resource
|
||||||
@@ -67,9 +67,9 @@ public class CompanyService extends ServiceImpl<CompanyMapper,CompanyPO> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<RecommendHotCompanyVO> listHot() {
|
public List<RecommendHotCompanyVO> listHot() {
|
||||||
LambdaQueryWrapper<CompanyPO> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<Company> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
queryWrapper.eq(CompanyPO::getHotRecommend, "1")
|
queryWrapper.eq(Company::getHotRecommend, "1")
|
||||||
.select(CompanyPO::getId, CompanyPO::getName);
|
.select(Company::getId, Company::getName);
|
||||||
|
|
||||||
return companyMapper.selectList(queryWrapper)
|
return companyMapper.selectList(queryWrapper)
|
||||||
.stream()
|
.stream()
|
||||||
@@ -86,8 +86,8 @@ public class CompanyService extends ServiceImpl<CompanyMapper,CompanyPO> {
|
|||||||
*/
|
*/
|
||||||
public boolean isNameExists(String name) {
|
public boolean isNameExists(String name) {
|
||||||
Long count = companyMapper.selectCount(
|
Long count = companyMapper.selectCount(
|
||||||
new LambdaQueryWrapper<CompanyPO>()
|
new LambdaQueryWrapper<Company>()
|
||||||
.eq(CompanyPO::getName, name)
|
.eq(Company::getName, name)
|
||||||
);
|
);
|
||||||
return count > 0;
|
return count > 0;
|
||||||
}
|
}
|
||||||
@@ -97,8 +97,8 @@ public class CompanyService extends ServiceImpl<CompanyMapper,CompanyPO> {
|
|||||||
*/
|
*/
|
||||||
public boolean isPhoneExists(String phone) {
|
public boolean isPhoneExists(String phone) {
|
||||||
Long count = companyMapper.selectCount(
|
Long count = companyMapper.selectCount(
|
||||||
new LambdaQueryWrapper<CompanyPO>()
|
new LambdaQueryWrapper<Company>()
|
||||||
.eq(CompanyPO::getPhone, phone)
|
.eq(Company::getPhone, phone)
|
||||||
);
|
);
|
||||||
return count > 0;
|
return count > 0;
|
||||||
}
|
}
|
||||||
@@ -108,8 +108,8 @@ public class CompanyService extends ServiceImpl<CompanyMapper,CompanyPO> {
|
|||||||
*/
|
*/
|
||||||
public boolean isEmailExists(String email) {
|
public boolean isEmailExists(String email) {
|
||||||
Long count = companyMapper.selectCount(
|
Long count = companyMapper.selectCount(
|
||||||
new LambdaQueryWrapper<CompanyPO>()
|
new LambdaQueryWrapper<Company>()
|
||||||
.eq(CompanyPO::getEmail, email)
|
.eq(Company::getEmail, email)
|
||||||
);
|
);
|
||||||
return count > 0;
|
return count > 0;
|
||||||
}
|
}
|
||||||
@@ -123,19 +123,19 @@ public class CompanyService extends ServiceImpl<CompanyMapper,CompanyPO> {
|
|||||||
List<String> industries = queryCompanyDTO.getIndustries();
|
List<String> industries = queryCompanyDTO.getIndustries();
|
||||||
|
|
||||||
// 分页
|
// 分页
|
||||||
Page<CompanyPO> companyPage = new Page<>(currentPage,pageSize);
|
Page<Company> companyPage = new Page<>(currentPage,pageSize);
|
||||||
LambdaQueryWrapper<CompanyPO> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<Company> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
|
||||||
// 名称
|
// 名称
|
||||||
if (StringUtils.isNotBlank(name)){
|
if (StringUtils.isNotBlank(name)){
|
||||||
queryWrapper.like(CompanyPO::getName,name);
|
queryWrapper.like(Company::getName,name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 地区
|
// 地区
|
||||||
if (areas != null && !areas.isEmpty()){
|
if (areas != null && !areas.isEmpty()){
|
||||||
queryWrapper.and(wrapper -> {
|
queryWrapper.and(wrapper -> {
|
||||||
for (String area : areas) {
|
for (String area : areas) {
|
||||||
wrapper.or(w -> w.like(CompanyPO::getArea, area));
|
wrapper.or(w -> w.like(Company::getArea, area));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -144,12 +144,12 @@ public class CompanyService extends ServiceImpl<CompanyMapper,CompanyPO> {
|
|||||||
if (industries != null && !industries.isEmpty()) {
|
if (industries != null && !industries.isEmpty()) {
|
||||||
queryWrapper.and(wrapper -> {
|
queryWrapper.and(wrapper -> {
|
||||||
for (String industry : industries) {
|
for (String industry : industries) {
|
||||||
wrapper.or(w -> w.like(CompanyPO::getIndustry, industry));
|
wrapper.or(w -> w.like(Company::getIndustry, industry));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
queryWrapper.eq(CompanyPO::getCanuse,"1");
|
queryWrapper.eq(Company::getCanuse,"1");
|
||||||
|
|
||||||
List<QueryCompanyVO> result = companyMapper.selectList(companyPage, queryWrapper).stream().map(item -> {
|
List<QueryCompanyVO> result = companyMapper.selectList(companyPage, queryWrapper).stream().map(item -> {
|
||||||
QueryCompanyVO queryCompanyVO = new QueryCompanyVO();
|
QueryCompanyVO queryCompanyVO = new QueryCompanyVO();
|
||||||
@@ -173,18 +173,18 @@ public class CompanyService extends ServiceImpl<CompanyMapper,CompanyPO> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CompanyDetailVO getCompanyDetail(Long companyId) {
|
public CompanyDetailVO getCompanyDetail(Long companyId) {
|
||||||
CompanyPO companyPO = companyMapper.selectById(companyId);
|
Company company = companyMapper.selectById(companyId);
|
||||||
List<CompanyUserPO> companyUserPOS = companyUserService.listByCompanyId(companyId);
|
List<CompanyUser> companyUsers = companyUserService.listByCompanyId(companyId);
|
||||||
|
|
||||||
CompanyDetailVO companyDetailVO = new CompanyDetailVO();
|
CompanyDetailVO companyDetailVO = new CompanyDetailVO();
|
||||||
|
|
||||||
BeanUtils.copyProperties(companyPO,companyDetailVO);
|
BeanUtils.copyProperties(company,companyDetailVO);
|
||||||
companyDetailVO.setAreas(Arrays.stream(companyPO.getArea().split(","))
|
companyDetailVO.setAreas(Arrays.stream(company.getArea().split(","))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
companyDetailVO.setIndustries(Arrays.stream(companyPO.getIndustry().split(","))
|
companyDetailVO.setIndustries(Arrays.stream(company.getIndustry().split(","))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
companyDetailVO.setUsers(companyUserPOS.stream()
|
companyDetailVO.setUsers(companyUsers.stream()
|
||||||
.map(item -> {
|
.map(item -> {
|
||||||
CompanyDetailVO.User user = new CompanyDetailVO.User();
|
CompanyDetailVO.User user = new CompanyDetailVO.User();
|
||||||
BeanUtils.copyProperties(item, user);
|
BeanUtils.copyProperties(item, user);
|
||||||
@@ -206,43 +206,42 @@ public class CompanyService extends ServiceImpl<CompanyMapper,CompanyPO> {
|
|||||||
String name = updateCompanyDTO.getName();
|
String name = updateCompanyDTO.getName();
|
||||||
String phone = updateCompanyDTO.getPhone();
|
String phone = updateCompanyDTO.getPhone();
|
||||||
String email = updateCompanyDTO.getEmail();
|
String email = updateCompanyDTO.getEmail();
|
||||||
Date establishmentDate = updateCompanyDTO.getEstablishmentDate();
|
|
||||||
String profile = updateCompanyDTO.getProfile();
|
|
||||||
String description = updateCompanyDTO.getDescription();
|
|
||||||
String logo = updateCompanyDTO.getLogo();
|
|
||||||
|
|
||||||
String area = StringUtils.join(updateCompanyDTO.getAreas(), ",");
|
String area = StringUtils.join(updateCompanyDTO.getAreas(), ",");
|
||||||
String industry = StringUtils.join(updateCompanyDTO.getIndustries(), ",");
|
String industry = StringUtils.join(updateCompanyDTO.getIndustries(), ",");
|
||||||
|
|
||||||
// 检查
|
// 检查
|
||||||
CompanyPO companyPO = companyMapper.selectById(id);
|
Company company = companyMapper.selectById(id);
|
||||||
if (ObjectUtils.isEmpty(companyPO)){
|
if (ObjectUtils.isEmpty(company)){
|
||||||
throw new BusinessException("更新失败,该公司不存在");
|
throw new BusinessException("更新失败,该公司不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查名称
|
// 检查名称
|
||||||
if (!companyPO.getName().equals(name) && isNameExists(name)){
|
if (!company.getName().equals(name) && isNameExists(name)){
|
||||||
throw new BusinessException("公司名称已存在");
|
throw new BusinessException("公司名称已存在");
|
||||||
}
|
}
|
||||||
// 检查联系电话
|
// 检查联系电话
|
||||||
if (!StringUtils.equals(phone, companyPO.getPhone())
|
if (!StringUtils.equals(phone, company.getPhone())
|
||||||
&& isPhoneExists(phone)) {
|
&& isPhoneExists(phone)) {
|
||||||
throw new BusinessException("公司联系电话已存在");
|
throw new BusinessException("公司联系电话已存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查邮箱
|
// 检查邮箱
|
||||||
if (!StringUtils.equals(email, companyPO.getEmail())
|
if (!StringUtils.equals(email, company.getEmail())
|
||||||
&& isEmailExists(email)) {
|
&& isEmailExists(email)) {
|
||||||
throw new BusinessException("公司联系邮箱已存在");
|
throw new BusinessException("公司联系邮箱已存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新
|
// 更新
|
||||||
BeanUtils.copyProperties(updateCompanyDTO,companyPO);
|
BeanUtils.copyProperties(updateCompanyDTO, company);
|
||||||
|
|
||||||
companyPO.setArea(area);
|
company.setArea(area);
|
||||||
companyPO.setIndustry(industry);
|
company.setIndustry(industry);
|
||||||
|
|
||||||
// 保存更新后的公司信息
|
// 保存更新后的公司信息
|
||||||
companyMapper.updateById(companyPO);
|
companyMapper.updateById(company);
|
||||||
|
|
||||||
|
// 更新用户头像
|
||||||
|
companyUserService.updateCompanyAvatar(company.getId(),company.getLogo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+69
-52
@@ -9,7 +9,7 @@ import cn.link56.company.model.dto.AddCompanyUserDTO;
|
|||||||
import cn.link56.company.model.dto.DeleteCompanyUserDTO;
|
import cn.link56.company.model.dto.DeleteCompanyUserDTO;
|
||||||
import cn.link56.company.model.dto.QueryCompanyUserDTO;
|
import cn.link56.company.model.dto.QueryCompanyUserDTO;
|
||||||
import cn.link56.company.model.dto.UpdateCompanyUserDTO;
|
import cn.link56.company.model.dto.UpdateCompanyUserDTO;
|
||||||
import cn.link56.company.model.po.CompanyUserPO;
|
import cn.link56.company.model.po.CompanyUser;
|
||||||
import cn.link56.company.model.vo.QueryCompanyUserVO;
|
import cn.link56.company.model.vo.QueryCompanyUserVO;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
@@ -26,7 +26,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class CompanyUserService extends ServiceImpl<CompanyUserMapper, CompanyUserPO> {
|
public class CompanyUserService extends ServiceImpl<CompanyUserMapper, CompanyUser> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private CompanyUserMapper companyUserMapper;
|
private CompanyUserMapper companyUserMapper;
|
||||||
@@ -41,8 +41,8 @@ public class CompanyUserService extends ServiceImpl<CompanyUserMapper, CompanyUs
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
long count = companyUserMapper.selectCount(
|
long count = companyUserMapper.selectCount(
|
||||||
new LambdaQueryWrapper<CompanyUserPO>()
|
new LambdaQueryWrapper<CompanyUser>()
|
||||||
.eq(CompanyUserPO::getEmail, email)
|
.eq(CompanyUser::getEmail, email)
|
||||||
);
|
);
|
||||||
return count > 0;
|
return count > 0;
|
||||||
}
|
}
|
||||||
@@ -54,13 +54,29 @@ public class CompanyUserService extends ServiceImpl<CompanyUserMapper, CompanyUs
|
|||||||
*/
|
*/
|
||||||
public boolean isPhoneExists(String phone) {
|
public boolean isPhoneExists(String phone) {
|
||||||
long count = companyUserMapper.selectCount(
|
long count = companyUserMapper.selectCount(
|
||||||
new LambdaQueryWrapper<CompanyUserPO>()
|
new LambdaQueryWrapper<CompanyUser>()
|
||||||
.eq(CompanyUserPO::getPhone, phone)
|
.eq(CompanyUser::getPhone, phone)
|
||||||
);
|
);
|
||||||
return count > 0;
|
return count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void updateCompanyAvatar(Long companyId, String avatar) {
|
||||||
|
if (StringUtils.isBlank(avatar)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LambdaUpdateWrapper<CompanyUser> wrapper = new LambdaUpdateWrapper<>();
|
||||||
|
wrapper.eq(CompanyUser::getCompanyId, companyId)
|
||||||
|
.and(w -> w.isNull(CompanyUser::getAvatar)
|
||||||
|
.or()
|
||||||
|
.eq(CompanyUser::getAvatar, ""))
|
||||||
|
.set(CompanyUser::getAvatar, avatar);
|
||||||
|
|
||||||
|
companyUserMapper.update(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验当前用户是否有权限操作指定的公司
|
* 校验当前用户是否有权限操作指定的公司
|
||||||
* @param companyId 当前公司ID
|
* @param companyId 当前公司ID
|
||||||
@@ -69,10 +85,10 @@ public class CompanyUserService extends ServiceImpl<CompanyUserMapper, CompanyUs
|
|||||||
*/
|
*/
|
||||||
public boolean hasPermission(Long companyId, Long userId) {
|
public boolean hasPermission(Long companyId, Long userId) {
|
||||||
// 根据 userId 查询公司用户信息
|
// 根据 userId 查询公司用户信息
|
||||||
CompanyUserPO companyUserPO = companyUserMapper.selectById(userId);
|
CompanyUser companyUser = companyUserMapper.selectById(userId);
|
||||||
|
|
||||||
// 如果 companyUserPO 为空,表示该用户不存在,直接返回无权限
|
// 如果 companyUserPO 为空,表示该用户不存在,直接返回无权限
|
||||||
if (ObjectUtils.isEmpty(companyUserPO)) {
|
if (ObjectUtils.isEmpty(companyUser)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,35 +98,35 @@ public class CompanyUserService extends ServiceImpl<CompanyUserMapper, CompanyUs
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 判断用户是否属于该公司
|
// 判断用户是否属于该公司
|
||||||
if (!companyUserPO.getCompanyId().equals(companyId)) {
|
if (!companyUser.getCompanyId().equals(companyId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查用户角色是否为 0,只有角色为 0 才有权限
|
// 检查用户角色是否为 0,只有角色为 0 才有权限
|
||||||
return companyUserPO.getRole() == 0;
|
return companyUser.getRole() == 0;
|
||||||
|
|
||||||
// 如果角色不是 0,表示没有权限
|
// 如果角色不是 0,表示没有权限
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CompanyUserPO loginByEmailAndPassword(String email, String password){
|
public CompanyUser loginByEmailAndPassword(String email, String password){
|
||||||
LambdaQueryWrapper<CompanyUserPO> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<CompanyUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
queryWrapper.eq(CompanyUserPO::getEmail,email)
|
queryWrapper.eq(CompanyUser::getEmail,email)
|
||||||
.eq(CompanyUserPO::getPassword,password);
|
.eq(CompanyUser::getPassword,password);
|
||||||
|
|
||||||
return companyUserMapper.selectOne(queryWrapper);
|
return companyUserMapper.selectOne(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompanyUserPO loginByEmail(String email){
|
public CompanyUser loginByEmail(String email){
|
||||||
LambdaQueryWrapper<CompanyUserPO> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<CompanyUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
queryWrapper.eq(CompanyUserPO::getEmail,email);
|
queryWrapper.eq(CompanyUser::getEmail,email);
|
||||||
|
|
||||||
return companyUserMapper.selectOne(queryWrapper);
|
return companyUserMapper.selectOne(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CompanyUserPO> listByCompanyId(Long companyId){
|
public List<CompanyUser> listByCompanyId(Long companyId){
|
||||||
LambdaQueryWrapper<CompanyUserPO> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<CompanyUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
queryWrapper.eq(CompanyUserPO::getCompanyId,companyId);
|
queryWrapper.eq(CompanyUser::getCompanyId,companyId);
|
||||||
|
|
||||||
return companyUserMapper.selectList(queryWrapper);
|
return companyUserMapper.selectList(queryWrapper);
|
||||||
}
|
}
|
||||||
@@ -132,34 +148,34 @@ public class CompanyUserService extends ServiceImpl<CompanyUserMapper, CompanyUs
|
|||||||
String position = queryCompanyUserDTO.getPosition();
|
String position = queryCompanyUserDTO.getPosition();
|
||||||
String canuse = queryCompanyUserDTO.getCanuse();
|
String canuse = queryCompanyUserDTO.getCanuse();
|
||||||
|
|
||||||
Page<CompanyUserPO> queryPage = new Page<>(currentPage,pageSize);
|
Page<CompanyUser> queryPage = new Page<>(currentPage,pageSize);
|
||||||
LambdaQueryWrapper<CompanyUserPO> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<CompanyUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
|
||||||
queryWrapper.eq(CompanyUserPO::getCompanyId,companyId);
|
queryWrapper.eq(CompanyUser::getCompanyId,companyId);
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(name)){
|
if (StringUtils.isNotBlank(name)){
|
||||||
queryWrapper.like(CompanyUserPO::getName,name);
|
queryWrapper.like(CompanyUser::getName,name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(email)){
|
if (StringUtils.isNotBlank(email)){
|
||||||
queryWrapper.like(CompanyUserPO::getEmail,email);
|
queryWrapper.like(CompanyUser::getEmail,email);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(phone)){
|
if (StringUtils.isNotBlank(phone)){
|
||||||
queryWrapper.like(CompanyUserPO::getPhone,phone);
|
queryWrapper.like(CompanyUser::getPhone,phone);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(position)){
|
if (StringUtils.isNotBlank(position)){
|
||||||
queryWrapper.like(CompanyUserPO::getPosition,position);
|
queryWrapper.like(CompanyUser::getPosition,position);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(canuse)){
|
if (StringUtils.isNotBlank(canuse)){
|
||||||
queryWrapper.eq(CompanyUserPO::getCanuse,canuse);
|
queryWrapper.eq(CompanyUser::getCanuse,canuse);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<CompanyUserPO> companyUserPOS = companyUserMapper.selectList(queryPage, queryWrapper);
|
List<CompanyUser> companyUsers = companyUserMapper.selectList(queryPage, queryWrapper);
|
||||||
|
|
||||||
List<QueryCompanyUserVO> result = companyUserPOS.stream().map(item -> {
|
List<QueryCompanyUserVO> result = companyUsers.stream().map(item -> {
|
||||||
QueryCompanyUserVO queryCompanyUserVO = new QueryCompanyUserVO();
|
QueryCompanyUserVO queryCompanyUserVO = new QueryCompanyUserVO();
|
||||||
BeanUtils.copyProperties(item, queryCompanyUserVO);
|
BeanUtils.copyProperties(item, queryCompanyUserVO);
|
||||||
return queryCompanyUserVO;
|
return queryCompanyUserVO;
|
||||||
@@ -192,14 +208,14 @@ public class CompanyUserService extends ServiceImpl<CompanyUserMapper, CompanyUs
|
|||||||
canuse = "1";
|
canuse = "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
CompanyUserPO companyUserPO = new CompanyUserPO();
|
CompanyUser companyUser = new CompanyUser();
|
||||||
|
|
||||||
BeanUtils.copyProperties(companyUserDTO,companyUserPO);
|
BeanUtils.copyProperties(companyUserDTO, companyUser);
|
||||||
companyUserPO.setId(IdGenerator.nextId());
|
companyUser.setId(IdGenerator.nextId());
|
||||||
companyUserPO.setRole(1);
|
companyUser.setRole(1);
|
||||||
companyUserPO.setCanuse(canuse);
|
companyUser.setCanuse(canuse);
|
||||||
|
|
||||||
companyUserMapper.insert(companyUserPO);
|
companyUserMapper.insert(companyUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -217,37 +233,38 @@ public class CompanyUserService extends ServiceImpl<CompanyUserMapper, CompanyUs
|
|||||||
throw new BusinessException("您没有权限访问该公司的信息,操作被拒绝");
|
throw new BusinessException("您没有权限访问该公司的信息,操作被拒绝");
|
||||||
}
|
}
|
||||||
|
|
||||||
CompanyUserPO companyUserPO = companyUserMapper.selectById(id);
|
CompanyUser companyUser = companyUserMapper.selectById(id);
|
||||||
String oldPassword = companyUserPO.getPassword();
|
String oldPassword = companyUser.getPassword();
|
||||||
|
|
||||||
if (ObjectUtils.isEmpty(companyUserPO)) {
|
if (ObjectUtils.isEmpty(companyUser)) {
|
||||||
throw new BusinessException("更新失败,该用户不存在");
|
throw new BusinessException("更新失败,该用户不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查邮箱是否发生变化
|
// 检查邮箱是否发生变化
|
||||||
boolean isEmailChanged = !StringUtils.equals(email, companyUserPO.getEmail());
|
boolean isEmailChanged = !StringUtils.equals(email, companyUser.getEmail());
|
||||||
if (isEmailChanged && isEmailExists(email)) {
|
if (isEmailChanged && isEmailExists(email)) {
|
||||||
throw new BusinessException("邮箱已被注册");
|
throw new BusinessException("邮箱已被注册");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查手机号是否发生变化
|
// 检查手机号是否发生变化
|
||||||
if (!StringUtils.equals(phone, companyUserPO.getPhone()) && isPhoneExists(phone)) {
|
if (!StringUtils.equals(phone, companyUser.getPhone()) && isPhoneExists(phone)) {
|
||||||
throw new BusinessException("手机号已被注册");
|
throw new BusinessException("手机号已被注册");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(password)) {
|
if (StringUtils.isNotBlank(password)) {
|
||||||
companyUserPO.setPassword(password);
|
companyUser.setPassword(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
BeanUtils.copyProperties(companyUserDTO, companyUserPO);
|
BeanUtils.copyProperties(companyUserDTO, companyUser);
|
||||||
if(StringUtils.isNotBlank(password)){
|
|
||||||
companyUserPO.setPassword(password);
|
if(StringUtils.isNotBlank(password)) {
|
||||||
}else{
|
companyUser.setPassword(password);
|
||||||
companyUserPO.setPassword(oldPassword);
|
} else {
|
||||||
|
companyUser.setPassword(oldPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新用户信息
|
// 更新用户信息
|
||||||
companyUserMapper.updateById(companyUserPO);
|
companyUserMapper.updateById(companyUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -261,10 +278,10 @@ public class CompanyUserService extends ServiceImpl<CompanyUserMapper, CompanyUs
|
|||||||
throw new BusinessException("您没有权限访问该公司的信息,操作被拒绝");
|
throw new BusinessException("您没有权限访问该公司的信息,操作被拒绝");
|
||||||
}
|
}
|
||||||
|
|
||||||
LambdaUpdateWrapper<CompanyUserPO> updateWrapper = new LambdaUpdateWrapper<>();
|
LambdaUpdateWrapper<CompanyUser> updateWrapper = new LambdaUpdateWrapper<>();
|
||||||
updateWrapper.in(CompanyUserPO::getId, ids)
|
updateWrapper.in(CompanyUser::getId, ids)
|
||||||
.eq(CompanyUserPO::getCompanyId, companyId)
|
.eq(CompanyUser::getCompanyId, companyId)
|
||||||
.ne(CompanyUserPO::getRole, 0);
|
.ne(CompanyUser::getRole, 0);
|
||||||
|
|
||||||
// 执行删除操作
|
// 执行删除操作
|
||||||
companyUserMapper.delete(updateWrapper);
|
companyUserMapper.delete(updateWrapper);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class PostCommentVO {
|
|||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public static class User{
|
public static class User {
|
||||||
private Long id;
|
private Long id;
|
||||||
private Long companyId;
|
private Long companyId;
|
||||||
private String name;
|
private String name;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@@ -14,6 +15,7 @@ public class PostCompanyVO {
|
|||||||
private String name;
|
private String name;
|
||||||
private String logo;
|
private String logo;
|
||||||
private String profile;
|
private String profile;
|
||||||
|
private Date establishmentDate;
|
||||||
private List<String> areas;
|
private List<String> areas;
|
||||||
private List<String> industries;
|
private List<String> industries;
|
||||||
}
|
}
|
||||||
+47
-40
@@ -41,61 +41,68 @@ public class PostCommentService extends ServiceImpl<PostCommentMapper, PostComme
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PostCommentVO> listPostComments(Long id) {
|
public List<PostCommentVO> listPostComments(Long postId) {
|
||||||
|
|
||||||
// 1. 查询所有评论
|
// 1. 查询所有评论
|
||||||
List<PostCommentVO> list = postCommentMapper.selectComments(id);
|
List<PostCommentVO> list = postCommentMapper.selectComments(postId);
|
||||||
|
|
||||||
// 2. 构建扁平化树形结构(所有子评论提升到根评论层级)
|
// 2. 构建 id -> comment 映射
|
||||||
List<PostCommentVO> rootComments = new ArrayList<>();
|
Map<Long, PostCommentVO> commentMap = new HashMap<>(list.size());
|
||||||
Map<Long, PostCommentVO> commentMap = new HashMap<>();
|
|
||||||
|
|
||||||
// 2.1 初始化映射并收集根评论
|
|
||||||
for (PostCommentVO comment : list) {
|
for (PostCommentVO comment : list) {
|
||||||
|
comment.setChildren(new ArrayList<>()); // 统一初始化
|
||||||
commentMap.put(comment.getId(), comment);
|
commentMap.put(comment.getId(), comment);
|
||||||
if (ObjectUtils.isEmpty(comment.getFatherId())) {
|
|
||||||
rootComments.add(comment);
|
|
||||||
comment.setChildren(new ArrayList<>()); // 提前初始化children
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.2 遍历所有评论,将子评论挂到根祖先的children中
|
// 3. 收集一级评论
|
||||||
|
List<PostCommentVO> rootComments = new ArrayList<>();
|
||||||
for (PostCommentVO comment : list) {
|
for (PostCommentVO comment : list) {
|
||||||
if (ObjectUtils.isEmpty(comment.getFatherId())) {
|
if (comment.getFatherId() == null) {
|
||||||
continue; // 跳过根评论
|
rootComments.add(comment);
|
||||||
}
|
|
||||||
|
|
||||||
// 查找当前评论的根祖先(追溯到没有fatherId的祖先)
|
|
||||||
PostCommentVO rootAncestor = null;
|
|
||||||
Long currentFatherId = comment.getFatherId();
|
|
||||||
while (true) {
|
|
||||||
PostCommentVO parent = commentMap.get(currentFatherId);
|
|
||||||
if (parent == null) break; // 父节点不存在,终止循环
|
|
||||||
|
|
||||||
if (ObjectUtils.isEmpty(comment.getFatherId())) {
|
|
||||||
rootAncestor = parent; // 找到根祖先
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
currentFatherId = parent.getFatherId(); // 继续向上查找
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 挂载到根祖先的children中
|
|
||||||
if (rootAncestor != null && rootAncestor.getChildren() != null) {
|
|
||||||
rootAncestor.getChildren().add(comment);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 按原始顺序排序(可选)
|
// 4. 将所有子评论挂到「根评论」的 children 中
|
||||||
rootComments.forEach(root -> {
|
for (PostCommentVO comment : list) {
|
||||||
if (root.getChildren() != null) {
|
|
||||||
// 根据需求排序,例如按创建时间升序
|
// 跳过一级评论
|
||||||
root.getChildren().sort(Comparator.comparing(PostCommentVO::getCreateTime));
|
if (comment.getFatherId() == null) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
PostCommentVO root = findRootComment(comment, commentMap);
|
||||||
|
if (root != null) {
|
||||||
|
root.getChildren().add(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 子评论排序(可选)
|
||||||
|
rootComments.forEach(root ->
|
||||||
|
root.getChildren().sort(
|
||||||
|
Comparator.comparing(PostCommentVO::getCreateTime)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return rootComments;
|
return rootComments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private PostCommentVO findRootComment(
|
||||||
|
PostCommentVO comment,
|
||||||
|
Map<Long, PostCommentVO> commentMap) {
|
||||||
|
|
||||||
|
PostCommentVO current = comment;
|
||||||
|
|
||||||
|
while (current.getFatherId() != null) {
|
||||||
|
PostCommentVO parent = commentMap.get(current.getFatherId());
|
||||||
|
if (parent == null) {
|
||||||
|
return null; // 数据异常,防御
|
||||||
|
}
|
||||||
|
current = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return current; // fatherId == null 的就是根评论
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public CreatePostCommentVO createPostComment(CreatePostCommentDTO dto) {
|
public CreatePostCommentVO createPostComment(CreatePostCommentDTO dto) {
|
||||||
PostComment postComment = new PostComment();
|
PostComment postComment = new PostComment();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import cn.link56.common.BasePageVO;
|
|||||||
import cn.link56.common.context.UserContext;
|
import cn.link56.common.context.UserContext;
|
||||||
import cn.link56.common.exception.BusinessException;
|
import cn.link56.common.exception.BusinessException;
|
||||||
import cn.link56.common.utils.snowflake.idgen.IdGenerator;
|
import cn.link56.common.utils.snowflake.idgen.IdGenerator;
|
||||||
import cn.link56.company.model.po.CompanyPO;
|
import cn.link56.company.model.po.Company;
|
||||||
import cn.link56.company.service.CompanyService;
|
import cn.link56.company.service.CompanyService;
|
||||||
import cn.link56.post.mapper.PostMapper;
|
import cn.link56.post.mapper.PostMapper;
|
||||||
import cn.link56.post.model.dto.*;
|
import cn.link56.post.model.dto.*;
|
||||||
@@ -16,13 +16,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -258,7 +256,6 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
|
|||||||
|
|
||||||
Long viewTotal = postViewService.getTotalByPostId(id);
|
Long viewTotal = postViewService.getTotalByPostId(id);
|
||||||
Long commentTotal = postCommentService.getTotalByPostId(id);
|
Long commentTotal = postCommentService.getTotalByPostId(id);
|
||||||
|
|
||||||
postVO.setViewCount(viewTotal);
|
postVO.setViewCount(viewTotal);
|
||||||
postVO.setCommentCount(commentTotal);
|
postVO.setCommentCount(commentTotal);
|
||||||
|
|
||||||
@@ -274,16 +271,16 @@ public class PostService extends ServiceImpl<PostMapper, Post> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PostCompanyVO getPostCompanyById(Long id) {
|
public PostCompanyVO getPostCompanyById(Long id) {
|
||||||
CompanyPO companyPO = companyService.getById(id);
|
Company company = companyService.getById(id);
|
||||||
if (companyPO == null){
|
if (company == null){
|
||||||
throw new BusinessException("该公司不存在或已注销");
|
throw new BusinessException("该公司不存在或已注销");
|
||||||
}
|
}
|
||||||
|
|
||||||
PostCompanyVO postCompanyVO = new PostCompanyVO();
|
PostCompanyVO postCompanyVO = new PostCompanyVO();
|
||||||
BeanUtils.copyProperties(companyPO,postCompanyVO);
|
BeanUtils.copyProperties(company,postCompanyVO);
|
||||||
|
|
||||||
postCompanyVO.setAreas(Arrays.stream(StringUtils.split(companyPO.getArea(),",")).collect(Collectors.toList()));
|
postCompanyVO.setAreas(Arrays.stream(StringUtils.split(company.getArea(),",")).collect(Collectors.toList()));
|
||||||
postCompanyVO.setIndustries(Arrays.stream(StringUtils.split(companyPO.getIndustry(),",")).collect(Collectors.toList()));
|
postCompanyVO.setIndustries(Arrays.stream(StringUtils.split(company.getIndustry(),",")).collect(Collectors.toList()));
|
||||||
|
|
||||||
return postCompanyVO;
|
return postCompanyVO;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -28,8 +28,8 @@
|
|||||||
|
|
||||||
<select id="selectComments" resultMap="CommentListMap">
|
<select id="selectComments" resultMap="CommentListMap">
|
||||||
SELECT c.*,
|
SELECT c.*,
|
||||||
pc.b_id AS pub_user_id,pc.b_company_id AS pub_company_id,pc.b_name AS pub_user_name,
|
pc.b_id AS pub_user_id,pc.b_company_id AS pub_company_id,pc.b_name AS pub_user_name,pc.b_avatar AS pub_user_avatar,
|
||||||
rc.b_id AS rep_user_id,rc.b_company_id AS rep_company_id,rc.b_name AS rep_company_id
|
rc.b_id AS rep_user_id,rc.b_company_id AS rep_company_id,rc.b_name AS rep_user_name,rc.b_avatar AS rep_user_avatar
|
||||||
FROM b_post_comment c
|
FROM b_post_comment c
|
||||||
LEFT JOIN b_company_user pc ON c.b_create_by = pc.b_id
|
LEFT JOIN b_company_user pc ON c.b_create_by = pc.b_id
|
||||||
LEFT JOIN b_company_user rc ON (
|
LEFT JOIN b_company_user rc ON (
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
|
defineOptions({ inheritAttrs: false })
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
url?: string
|
||||||
|
size?: number
|
||||||
|
width?: number
|
||||||
|
height?: number
|
||||||
|
round?: boolean
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const fallback = '/no-avatar.png'
|
||||||
|
const currentSrc = ref(props.url?.trim() || fallback)
|
||||||
|
|
||||||
|
// 监听 url 变化
|
||||||
|
watch(
|
||||||
|
() => props.url,
|
||||||
|
(newUrl) => {
|
||||||
|
currentSrc.value = newUrl?.trim() || fallback
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// 加载失败兜底
|
||||||
|
function onError() {
|
||||||
|
currentSrc.value = fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尺寸样式
|
||||||
|
const sizeStyle = computed(() => {
|
||||||
|
// width / height 优先
|
||||||
|
if (props.width || props.height) {
|
||||||
|
return {
|
||||||
|
width: props.width ? `${props.width}px` : undefined,
|
||||||
|
height: props.height ? `${props.height}px` : undefined,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// size(正方形)
|
||||||
|
if (typeof props.size === 'number') {
|
||||||
|
return {
|
||||||
|
width: `${props.size}px`,
|
||||||
|
height: `${props.size}px`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<img
|
||||||
|
v-bind="$attrs"
|
||||||
|
:src="currentSrc"
|
||||||
|
alt="图片"
|
||||||
|
class="base-img"
|
||||||
|
:class="{ 'is-round': round }"
|
||||||
|
:style="sizeStyle"
|
||||||
|
@error="onError"
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.base-img {
|
||||||
|
display: block;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 圆形 */
|
||||||
|
.is-round {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -4,6 +4,8 @@ import {
|
|||||||
User,
|
User,
|
||||||
} from '@element-plus/icons-vue'
|
} from '@element-plus/icons-vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import SafeImage from '@/components/SafeImage.vue'
|
||||||
|
|
||||||
import { useUserStore } from '@/store/user'
|
import { useUserStore } from '@/store/user'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -63,7 +65,7 @@ function isActive(path: string) {
|
|||||||
|
|
||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
<div class="user">
|
<div class="user">
|
||||||
<el-avatar :size="36" :src="userStore.userInfo.company.logo ? userStore.userInfo.company.logo : '/no-avatar.png'" />
|
<SafeImage :size="36" :url="userStore.userInfo.user.avatar || userStore.userInfo.company.logo" />
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span class="name">{{ userStore.userInfo.user.name }}</span>
|
<span class="name">{{ userStore.userInfo.user.name }}</span>
|
||||||
<span class="company">{{ userStore.userInfo.company.name }}</span>
|
<span class="company">{{ userStore.userInfo.company.name }}</span>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const router = createRouter({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/company/detail',
|
path: '/company/detail',
|
||||||
component: () => import('@/views/company/detail/index.vue'),
|
component: () => import('@/views/company/detail.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/settings',
|
path: '/settings',
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ interface IUserInfo {
|
|||||||
name: string
|
name: string
|
||||||
position: string
|
position: string
|
||||||
role: number
|
role: number
|
||||||
|
avatar: string
|
||||||
}
|
}
|
||||||
company: {
|
company: {
|
||||||
id: number
|
id: number
|
||||||
@@ -25,6 +26,7 @@ export const useUserStore = defineStore(
|
|||||||
name: '',
|
name: '',
|
||||||
position: '',
|
position: '',
|
||||||
role: 0,
|
role: 0,
|
||||||
|
avatar: '',
|
||||||
},
|
},
|
||||||
company: {
|
company: {
|
||||||
id: 0,
|
id: 0,
|
||||||
@@ -45,6 +47,7 @@ export const useUserStore = defineStore(
|
|||||||
name: '',
|
name: '',
|
||||||
position: '',
|
position: '',
|
||||||
role: 0,
|
role: 0,
|
||||||
|
avatar: '',
|
||||||
},
|
},
|
||||||
company: {
|
company: {
|
||||||
id: 0,
|
id: 0,
|
||||||
|
|||||||
@@ -9,14 +9,18 @@ export interface LoginEmailCodeApiParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface LoginApiResult {
|
export interface LoginApiResult {
|
||||||
companyId: number
|
company: {
|
||||||
companyLogo: string
|
id: number
|
||||||
companyName: string
|
logo: string
|
||||||
|
name: string
|
||||||
userId: number
|
}
|
||||||
userRole: number
|
user: {
|
||||||
userName: string
|
id: number
|
||||||
userPosition: string
|
role: number
|
||||||
|
name: string
|
||||||
|
position: string
|
||||||
|
avatar: string
|
||||||
|
}
|
||||||
|
|
||||||
token: string
|
token: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export interface CompanyUser {
|
|||||||
email: string
|
email: string
|
||||||
phone: string
|
phone: string
|
||||||
canuse: string
|
canuse: string
|
||||||
|
avatar: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CompanyUserForm extends CompanyUser {
|
export interface CompanyUserForm extends CompanyUser {
|
||||||
@@ -34,6 +35,8 @@ export interface AddCompanyUserParams {
|
|||||||
position: string
|
position: string
|
||||||
phone: string
|
phone: string
|
||||||
canuse: string
|
canuse: string
|
||||||
|
|
||||||
|
avatar: string
|
||||||
}
|
}
|
||||||
export interface UpdateCompanyUserParams {
|
export interface UpdateCompanyUserParams {
|
||||||
id: number
|
id: number
|
||||||
@@ -46,6 +49,8 @@ export interface UpdateCompanyUserParams {
|
|||||||
position: string
|
position: string
|
||||||
phone: string
|
phone: string
|
||||||
canuse: string
|
canuse: string
|
||||||
|
|
||||||
|
avatar: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeleteCompanyUserParams {
|
export interface DeleteCompanyUserParams {
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ export interface PublicPostDetail {
|
|||||||
activeTime: string
|
activeTime: string
|
||||||
|
|
||||||
viewCount: number
|
viewCount: number
|
||||||
commentCount: number
|
|
||||||
|
|
||||||
companyId: number
|
companyId: number
|
||||||
}
|
}
|
||||||
@@ -68,6 +67,7 @@ export interface PostCompany {
|
|||||||
name: string
|
name: string
|
||||||
logo: string
|
logo: string
|
||||||
profile: string
|
profile: string
|
||||||
|
establishmentDate: string
|
||||||
|
|
||||||
areas: string[]
|
areas: string[]
|
||||||
industries: string[]
|
industries: string[]
|
||||||
|
|||||||
@@ -44,3 +44,69 @@ export function formatPostTime(input?: dayjs.ConfigType): string {
|
|||||||
// 非本年
|
// 非本年
|
||||||
return time.format('YYYY年MM月DD日')
|
return time.format('YYYY年MM月DD日')
|
||||||
}
|
}
|
||||||
|
export function formatCommentTime(input?: dayjs.ConfigType): string {
|
||||||
|
if (!input)
|
||||||
|
return ''
|
||||||
|
|
||||||
|
const time = dayjs(input)
|
||||||
|
if (!time.isValid())
|
||||||
|
return ''
|
||||||
|
|
||||||
|
const now = dayjs()
|
||||||
|
const diffSeconds = now.diff(time, 'second')
|
||||||
|
|
||||||
|
// 未来时间兜底
|
||||||
|
if (diffSeconds < 0) {
|
||||||
|
return time.format('YYYY-MM-DD HH:mm')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1 分钟内
|
||||||
|
if (diffSeconds < 60) {
|
||||||
|
return '刚刚'
|
||||||
|
}
|
||||||
|
|
||||||
|
const diffMinutes = now.diff(time, 'minute')
|
||||||
|
if (diffMinutes < 60) {
|
||||||
|
return `${diffMinutes}分钟前`
|
||||||
|
}
|
||||||
|
|
||||||
|
const diffHours = now.diff(time, 'hour')
|
||||||
|
if (diffHours < 24) {
|
||||||
|
return `${diffHours}小时前`
|
||||||
|
}
|
||||||
|
|
||||||
|
const diffDays = now.diff(time, 'day')
|
||||||
|
if (diffDays < 7) {
|
||||||
|
return `${diffDays}天前`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本年
|
||||||
|
if (time.year() === now.year()) {
|
||||||
|
return time.format('MM-DD HH:mm')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非本年
|
||||||
|
return time.format('YYYY-MM-DD HH:mm')
|
||||||
|
}
|
||||||
|
export type DateFormat
|
||||||
|
= | 'YYYY'
|
||||||
|
| 'MM'
|
||||||
|
| 'DD'
|
||||||
|
| 'YYYY-MM-DD'
|
||||||
|
| 'YYYY-MM-DD HH:mm'
|
||||||
|
| 'YYYY-MM-DD HH:mm:ss'
|
||||||
|
| 'YYYY年MM月DD日'
|
||||||
|
|
||||||
|
export function formatDate(
|
||||||
|
input?: dayjs.ConfigType,
|
||||||
|
format: DateFormat = 'YYYY-MM-DD',
|
||||||
|
): string {
|
||||||
|
if (!input)
|
||||||
|
return ''
|
||||||
|
|
||||||
|
const date = dayjs(input)
|
||||||
|
if (!date.isValid())
|
||||||
|
return ''
|
||||||
|
|
||||||
|
return date.format(format)
|
||||||
|
}
|
||||||
@@ -133,20 +133,7 @@ async function submitForm(formEl: FormInstance | undefined) {
|
|||||||
if (res.isSuccess) {
|
if (res.isSuccess) {
|
||||||
ElMessage.success('登录成功')
|
ElMessage.success('登录成功')
|
||||||
|
|
||||||
userStore.setUserInfo({
|
userStore.setUserInfo(res.data)
|
||||||
user: {
|
|
||||||
id: res.data.userId,
|
|
||||||
name: res.data.userName,
|
|
||||||
position: res.data.userPosition,
|
|
||||||
role: res.data.userRole,
|
|
||||||
},
|
|
||||||
company: {
|
|
||||||
id: res.data.companyId,
|
|
||||||
logo: res.data.companyLogo,
|
|
||||||
name: res.data.companyName,
|
|
||||||
},
|
|
||||||
token: res.data.token,
|
|
||||||
})
|
|
||||||
|
|
||||||
router.push('/')
|
router.push('/')
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-4
@@ -8,6 +8,7 @@ import AnchorMenu from '@/components/anchor-menu/index.vue'
|
|||||||
|
|
||||||
import WangEditor from '@/components/wang-editor/index.vue'
|
import WangEditor from '@/components/wang-editor/index.vue'
|
||||||
import { getCompanyDetailApi } from '@/request/api/company'
|
import { getCompanyDetailApi } from '@/request/api/company'
|
||||||
|
import { formatDate } from '@/utils/time'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -110,14 +111,11 @@ function handleUpdateEditorDirectory(menus: AnchorMenuItem[]) {
|
|||||||
{{ companyDetail.email || '-' }}
|
{{ companyDetail.email || '-' }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="成立日期">
|
<el-descriptions-item label="成立日期">
|
||||||
-
|
{{ formatDate(companyDetail.establishmentDate, 'YYYY-MM-DD') || '-' }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="区域">
|
<el-descriptions-item label="区域">
|
||||||
{{ companyDetail.areas.join('/') || '-' }}
|
{{ companyDetail.areas.join('/') || '-' }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="详细地址" :span="2">
|
|
||||||
-
|
|
||||||
</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -135,6 +133,13 @@ function handleUpdateEditorDirectory(menus: AnchorMenuItem[]) {
|
|||||||
<span class="info-title">公司成员</span>
|
<span class="info-title">公司成员</span>
|
||||||
</div>
|
</div>
|
||||||
<el-table :data="companyDetail.users" style="width: 100%" stripe border>
|
<el-table :data="companyDetail.users" style="width: 100%" stripe border>
|
||||||
|
<el-table-column prop="avatar" label="头像" align="center" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<div style="display: flex;align-items: center;justify-content: center;">
|
||||||
|
<SafeImage :url="scope.row.avatar" :size="64" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="name" label="姓名" width="180" />
|
<el-table-column prop="name" label="姓名" width="180" />
|
||||||
<el-table-column prop="position" label="职务" width="180" />
|
<el-table-column prop="position" label="职务" width="180" />
|
||||||
<el-table-column prop="phone" label="手机号" width="180" />
|
<el-table-column prop="phone" label="手机号" width="180" />
|
||||||
@@ -4,6 +4,7 @@ import { ElMessage } from 'element-plus'
|
|||||||
import { onMounted, reactive, ref } from 'vue'
|
import { onMounted, reactive, ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import QueryCompany from '@/components/QueryCompany.vue'
|
import QueryCompany from '@/components/QueryCompany.vue'
|
||||||
|
import SafeImage from '@/components/SafeImage.vue'
|
||||||
import { queryCompanyApi } from '@/request/api/company'
|
import { queryCompanyApi } from '@/request/api/company'
|
||||||
import { useCommonStore } from '@/store/common'
|
import { useCommonStore } from '@/store/common'
|
||||||
|
|
||||||
@@ -77,21 +78,22 @@ function toDetail(data: Company) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="company-list">
|
<div class="company-list">
|
||||||
<div v-for="item in companyList" :key="item.id" class="company-item">
|
<div v-for="item in companyList" :key="item.id" class="company-item">
|
||||||
<el-avatar shape="square" :src="item.logo || '/no-avatar.png'" :size="70" class="company-logo" />
|
<SafeImage :url="item.logo" :size="70" class="company-logo" />
|
||||||
|
|
||||||
<div class="company-info">
|
<div class="company-info">
|
||||||
<div class="company-header">
|
<div class="company-header">
|
||||||
<div class="company-name">
|
<div class="company-name" @click="toDetail(item)">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="company-tags">
|
||||||
|
<el-tag v-for="tag in item.industries" :key="tag" type="primary" effect="dark">
|
||||||
|
{{ tag }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="company-tags">
|
|
||||||
<el-tag v-for="tag in item.industries" :key="tag" type="primary" effect="dark">
|
<p v-if="item.profile" class="company-profile">
|
||||||
{{ tag }}
|
{{ item.profile }}
|
||||||
</el-tag>
|
|
||||||
</div>
|
|
||||||
<p class="company-profile">
|
|
||||||
{{ item.profile || '-' }}
|
|
||||||
</p>
|
</p>
|
||||||
<div class="company-footer">
|
<div class="company-footer">
|
||||||
<div class="company-details">
|
<div class="company-details">
|
||||||
@@ -109,7 +111,7 @@ function toDetail(data: Company) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="company-actions">
|
<div class="company-actions">
|
||||||
<el-button @click="toDetail(item)">
|
<!-- <el-button @click="toDetail(item)">
|
||||||
<i-ri:information-2-line />
|
<i-ri:information-2-line />
|
||||||
<span class="button-text">
|
<span class="button-text">
|
||||||
详细
|
详细
|
||||||
@@ -121,7 +123,7 @@ function toDetail(data: Company) {
|
|||||||
<span class="button-text">
|
<span class="button-text">
|
||||||
发起聊天
|
发起聊天
|
||||||
</span>
|
</span>
|
||||||
</el-button>
|
</el-button> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -202,7 +204,7 @@ function toDetail(data: Company) {
|
|||||||
|
|
||||||
.company-info {
|
.company-info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
min-height: 70px;
|
||||||
.company-header {
|
.company-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -219,7 +221,8 @@ function toDetail(data: Company) {
|
|||||||
|
|
||||||
.company-tags {
|
.company-tags {
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
> * {
|
|
||||||
|
> *:not(:last-child) {
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
import type { PostComment, PublicPostDetail } from '@/types/post'
|
import type { PostComment, PublicPostDetail } from '@/types/post'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { nextTick, ref, watch } from 'vue'
|
import { nextTick, ref, watch } from 'vue'
|
||||||
|
import SafeImage from '@/components/SafeImage.vue'
|
||||||
|
|
||||||
import SvgIcon from '@/components/SvgIcon.vue'
|
import SvgIcon from '@/components/SvgIcon.vue'
|
||||||
import { createPostCommentApi } from '@/request/api/post'
|
import { createPostCommentApi } from '@/request/api/post'
|
||||||
import { useUserStore } from '@/store/user'
|
import { useUserStore } from '@/store/user'
|
||||||
|
import { formatCommentTime } from '@/utils/time'
|
||||||
import CommentInput from './comment-input.vue'
|
import CommentInput from './comment-input.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -12,6 +15,11 @@ const props = defineProps<{
|
|||||||
postDetail: PublicPostDetail
|
postDetail: PublicPostDetail
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const emits = defineEmits<{
|
||||||
|
(e: 'update:modelValue', value: PostComment[]): void
|
||||||
|
(e: 'change'): void
|
||||||
|
}>()
|
||||||
|
|
||||||
const commentList = ref<PostComment[]>([])
|
const commentList = ref<PostComment[]>([])
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
|
|
||||||
@@ -29,19 +37,36 @@ watch(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
function handleReplyComment(commentId: number) {
|
function handleReplyComment(commentId: number, e: MouseEvent) {
|
||||||
if (replyCommentId.value === commentId) {
|
const isOpen = replyCommentId.value !== commentId
|
||||||
replyCommentId.value = null
|
replyCommentId.value = isOpen ? commentId : null
|
||||||
}
|
|
||||||
else {
|
if (!isOpen)
|
||||||
replyCommentId.value = commentId
|
return
|
||||||
}
|
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
window.scrollTo({
|
const el = e.currentTarget as HTMLElement
|
||||||
top: document.documentElement.scrollHeight,
|
if (!el)
|
||||||
behavior: 'smooth',
|
return
|
||||||
})
|
|
||||||
|
const rect = el.getBoundingClientRect()
|
||||||
|
const viewportHeight = window.innerHeight
|
||||||
|
const scrollOffset = 70 // 👈 可调:40~70
|
||||||
|
|
||||||
|
// 点击点在视口上半部分 → 往上滚
|
||||||
|
if (rect.top < viewportHeight / 2) {
|
||||||
|
window.scrollBy({
|
||||||
|
top: -scrollOffset,
|
||||||
|
behavior: 'smooth',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 点击点在视口下半部分 → 往下滚
|
||||||
|
else {
|
||||||
|
window.scrollBy({
|
||||||
|
top: scrollOffset,
|
||||||
|
behavior: 'smooth',
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +154,9 @@ function handleReplyCommentSubmit(content: string) {
|
|||||||
replyUser: null,
|
replyUser: null,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emits('update:modelValue', commentList.value)
|
||||||
|
emits('change')
|
||||||
})
|
})
|
||||||
|
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
@@ -141,7 +169,7 @@ function handleReplyCommentSubmit(content: string) {
|
|||||||
<template>
|
<template>
|
||||||
<div v-for="item in commentList" :key="item.id" class="custom-comment">
|
<div v-for="item in commentList" :key="item.id" class="custom-comment">
|
||||||
<div class="custom-comment-left">
|
<div class="custom-comment-left">
|
||||||
<el-avatar class="custom-comment-avatar" :src="item.publishUser.avatar || '/no-avatar.png'" :size="70" />
|
<SafeImage :url="item.publishUser.avatar" :size="32" round />
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-comment-right">
|
<div class="custom-comment-right">
|
||||||
<div class="custom-comment-meta">
|
<div class="custom-comment-meta">
|
||||||
@@ -149,33 +177,36 @@ function handleReplyCommentSubmit(content: string) {
|
|||||||
<div class="custom-comment-author">
|
<div class="custom-comment-author">
|
||||||
{{ item.publishUser.name }}
|
{{ item.publishUser.name }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.publishUser.companyId === postDetail.companyId" class="custom-comment-author-tag">
|
<!-- <div v-if="item.publishUser.companyId === postDetail.companyId" class="custom-comment-author-tag">
|
||||||
作者
|
作者
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-comment-time">
|
<div class="custom-comment-time">
|
||||||
{{ item.createTime }}
|
{{ formatCommentTime(item.createTime) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-comment-content" v-html="item.content" />
|
<div class="custom-comment-content" v-html="item.content" />
|
||||||
<div class="custom-comment-actions">
|
<div class="custom-comment-actions">
|
||||||
<div class="custom-comment-action" :style="{ color: replyCommentId === item.id ? '#165dff' : '#1d2129' }" @click="handleReplyComment(item.id)">
|
<div
|
||||||
<SvgIcon icon="mingcute:message-3-line" />
|
class="custom-comment-action" :style="{ color: replyCommentId === item.id ? '#165dff' : '#8A919F' }"
|
||||||
|
@click="handleReplyComment(item.id, $event)"
|
||||||
|
>
|
||||||
|
<SvgIcon icon="mingcute:message-3-line" :size="16" />
|
||||||
<div>{{ replyCommentId === item.id ? "取消回复" : "回复" }}</div>
|
<div>{{ replyCommentId === item.id ? "取消回复" : "回复" }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-comment-action flex ml-auto">
|
<div class="custom-comment-action" style="margin-left: auto;">
|
||||||
<SvgIcon icon="akar-icons:more-horizontal-fill" />
|
<SvgIcon icon="mingcute:more-1-fill" :size="16" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 父级评论输入框 -->
|
<!-- 父级评论输入框 -->
|
||||||
<CommentInput v-if="replyCommentId === item.id" :loading="replyCommentLoading" @submit="handleReplyCommentSubmit" />
|
<CommentInput v-if="replyCommentId === item.id" :loading="replyCommentLoading" style="margin-top: 8px;" @submit="handleReplyCommentSubmit" />
|
||||||
|
|
||||||
<!-- 子评论 -->
|
<!-- 子评论 -->
|
||||||
<div v-if="item.children && item.children.length > 0" class="custom-comment-children">
|
<div v-if="item.children && item.children.length > 0" class="custom-comment-children">
|
||||||
<div v-for="child in item.children" :key="child.id" class="custom-comment">
|
<div v-for="child in item.children" :key="child.id" class="custom-comment">
|
||||||
<div class="custom-comment-left">
|
<div class="custom-comment-left">
|
||||||
<el-avatar class="custom-comment-avatar" :src="item.publishUser.avatar || '/no-avatar.png'" :size="70" />
|
<SafeImage :url="item.publishUser.avatar" :size="32" round />
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-comment-right">
|
<div class="custom-comment-right">
|
||||||
<div class="custom-comment-meta">
|
<div class="custom-comment-meta">
|
||||||
@@ -183,33 +214,36 @@ function handleReplyCommentSubmit(content: string) {
|
|||||||
<div class="custom-comment-author">
|
<div class="custom-comment-author">
|
||||||
{{ child.publishUser.name }}
|
{{ child.publishUser.name }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="child.publishUser.companyId === postDetail.companyId" class="custom-comment-author-tag">
|
<!-- <div v-if="child.publishUser.companyId === postDetail.companyId" class="custom-comment-author-tag">
|
||||||
作者
|
作者
|
||||||
</div>
|
</div> -->
|
||||||
<template v-if="child.replyUser && child.fatherId !== item.id">
|
<template v-if="child.replyUser && child.fatherId !== item.id">
|
||||||
<div>回复</div>
|
<div style="margin: 0px 4px;">
|
||||||
|
回复
|
||||||
|
</div>
|
||||||
<div class="custom-comment-author">
|
<div class="custom-comment-author">
|
||||||
{{ child.replyUser.name }}
|
{{ child.replyUser.name }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-comment-time">
|
<div class="custom-comment-time">
|
||||||
{{ child.createTime }}
|
{{ formatCommentTime(child.createTime) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-comment-content">
|
<div class="custom-comment-content">
|
||||||
{{ child.content }}
|
{{ child.content }}
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-comment-actions">
|
<div class="custom-comment-actions">
|
||||||
<div class="custom-comment-action" :style="{ color: replyCommentId === child.id ? '#165dff' : '#1d2129' }" @click="handleReplyComment(child.id)">
|
<div class="custom-comment-action" :style="{ color: replyCommentId === child.id ? '#165dff' : '#8A919F' }" @click="handleReplyComment(child.id, $event)">
|
||||||
<SvgIcon icon="mingcute:message-3-line" />
|
<SvgIcon icon="mingcute:message-3-line" :size="16" />
|
||||||
<div>{{ replyCommentId === child.id ? "取消回复" : "回复" }}</div>
|
<div>{{ replyCommentId === child.id ? "取消回复" : "回复" }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="custom-comment-action flex ml-auto">
|
<div class="custom-comment-action" style="margin-left: auto;">
|
||||||
<SvgIcon icon="akar-icons:more-horizontal-fill" />
|
<SvgIcon icon="akar-icons:more-horizontal-fill" :size="16" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CommentInput v-if="replyCommentId === child.id" :loading="replyCommentLoading" @submit="handleReplyCommentSubmit" />
|
|
||||||
|
<CommentInput v-if="replyCommentId === child.id" :loading="replyCommentLoading" style="margin-top: 8px;" @submit="handleReplyCommentSubmit" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -238,21 +272,17 @@ function handleReplyCommentSubmit(content: string) {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
gap: 8px;
|
|
||||||
}
|
}
|
||||||
.custom-comment-avatar {
|
.custom-comment-avatar {
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 50%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
}
|
||||||
.custom-comment-meta {
|
.custom-comment-meta {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
margin-bottom: 4px;
|
||||||
.custom-comment-title {
|
.custom-comment-title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #4e5969;
|
color: #515767;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
@@ -274,14 +304,15 @@ function handleReplyCommentSubmit(content: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.custom-comment-content {
|
.custom-comment-content {
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
color: #1d2129;
|
color: #252933;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
|
margin-bottom: 6px;
|
||||||
}
|
}
|
||||||
.custom-comment-actions {
|
.custom-comment-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
gap: 12px;
|
||||||
.custom-comment-action {
|
.custom-comment-action {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
@@ -289,7 +320,7 @@ function handleReplyCommentSubmit(content: string) {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
color: #1d2129;
|
color: #8a919f;
|
||||||
}
|
}
|
||||||
.custom-comment-action:hover {
|
.custom-comment-action:hover {
|
||||||
color: #165dff;
|
color: #165dff;
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
import type { AnchorMenuItem } from '@/components/anchor-menu/type'
|
import type { AnchorMenuItem } from '@/components/anchor-menu/type'
|
||||||
import type { PostComment, PostCompany, PublicPostDetail } from '@/types/post'
|
import type { PostComment, PostCompany, PublicPostDetail } from '@/types/post'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { onMounted, ref } from 'vue'
|
import { computed, onMounted, ref } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import AnchorMenu from '@/components/anchor-menu/index.vue'
|
import AnchorMenu from '@/components/anchor-menu/index.vue'
|
||||||
import CustomEmpty from '@/components/CustomEmpty.vue'
|
import CustomEmpty from '@/components/CustomEmpty.vue'
|
||||||
import WandEditor from '@/components/wang-editor/index.vue'
|
import WandEditor from '@/components/wang-editor/index.vue'
|
||||||
import { createPostCommentApi, getPostCompanyById, getPublicPostDetailApi, listPostCommentApi } from '@/request/api/post'
|
import { createPostCommentApi, getPostCompanyById, getPublicPostDetailApi, listPostCommentApi } from '@/request/api/post'
|
||||||
import { useUserStore } from '@/store/user'
|
import { useUserStore } from '@/store/user'
|
||||||
import { formatPostTime } from '@/utils/time'
|
import { formatDate, formatPostTime } from '@/utils/time'
|
||||||
import CommentInput from './components/comment-input.vue'
|
import CommentInput from './components/comment-input.vue'
|
||||||
import CommentList from './components/comment-list.vue'
|
import CommentList from './components/comment-list.vue'
|
||||||
|
|
||||||
@@ -25,6 +25,7 @@ const postCompany = ref<PostCompany>({
|
|||||||
name: '',
|
name: '',
|
||||||
logo: '',
|
logo: '',
|
||||||
profile: '',
|
profile: '',
|
||||||
|
establishmentDate: '',
|
||||||
areas: [],
|
areas: [],
|
||||||
industries: [],
|
industries: [],
|
||||||
})
|
})
|
||||||
@@ -37,7 +38,6 @@ const postDetail = ref<PublicPostDetail>({
|
|||||||
activeTime: '',
|
activeTime: '',
|
||||||
|
|
||||||
viewCount: 0,
|
viewCount: 0,
|
||||||
commentCount: 0,
|
|
||||||
|
|
||||||
companyId: 0,
|
companyId: 0,
|
||||||
})
|
})
|
||||||
@@ -92,6 +92,22 @@ onMounted(async () => {
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
function getTotalCommentCount(list: PostComment[]): number {
|
||||||
|
let count = 0
|
||||||
|
|
||||||
|
for (const comment of list) {
|
||||||
|
count += 1 // 一级评论
|
||||||
|
if (comment.children && comment.children.length > 0) {
|
||||||
|
count += comment.children.length // 所有子评论(已扁平)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalCommentCount = computed(() => {
|
||||||
|
return getTotalCommentCount(postComments.value)
|
||||||
|
})
|
||||||
|
|
||||||
function handleUpdateEditorDirectory(menus: AnchorMenuItem[]) {
|
function handleUpdateEditorDirectory(menus: AnchorMenuItem[]) {
|
||||||
anchorMenu.value = anchorMenu.value.concat(menus)
|
anchorMenu.value = anchorMenu.value.concat(menus)
|
||||||
@@ -161,7 +177,7 @@ function handleSubmitRootComment(content: string) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="post-meta-item">
|
<div class="post-meta-item">
|
||||||
<SvgIcon icon="mdi:comment-outline" :size="16" />
|
<SvgIcon icon="mdi:comment-outline" :size="16" />
|
||||||
<span>{{ postDetail.commentCount }} </span>
|
<span>{{ totalCommentCount }} </span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -185,7 +201,10 @@ function handleSubmitRootComment(content: string) {
|
|||||||
|
|
||||||
<div class="reply-comment">
|
<div class="reply-comment">
|
||||||
<div v-if="postComments.length > 0" class="reply-comment-list">
|
<div v-if="postComments.length > 0" class="reply-comment-list">
|
||||||
<CommentList v-model="postComments" :post-detail="postDetail" />
|
<CommentList
|
||||||
|
v-model="postComments"
|
||||||
|
:post-detail="postDetail"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<CustomEmpty v-else title="暂时没有评论 🤔" :in-container="true" />
|
<CustomEmpty v-else title="暂时没有评论 🤔" :in-container="true" />
|
||||||
</div>
|
</div>
|
||||||
@@ -200,10 +219,11 @@ function handleSubmitRootComment(content: string) {
|
|||||||
<h3 class="company-name">
|
<h3 class="company-name">
|
||||||
{{ postCompany.name }}
|
{{ postCompany.name }}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div v-if="postCompany.areas.length > 0" class="company-meta">
|
<div v-if="postCompany.areas.length > 0" class="company-meta">
|
||||||
<!-- 成立于 2012 年 · 上海 -->
|
<template v-if="postCompany.establishmentDate">
|
||||||
{{ postCompany.areas.join("/") }}
|
成立于 {{ formatDate(postCompany.establishmentDate, 'YYYY') }} 年 ·
|
||||||
|
</template>
|
||||||
|
{{ postCompany.areas.join('/') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="company-desc">
|
<div class="company-desc">
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import type { DashboardData } from '@/types/post'
|
|||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
import CustomLoading from '@/components/CustomLoading.vue'
|
import CustomLoading from '@/components/CustomLoading.vue'
|
||||||
import { getDashboardDataApi } from '@/request/api/post'
|
|
||||||
import PostNumberChart from './components/post-number-chart.vue'
|
import PostNumberChart from './components/post-number-chart.vue'
|
||||||
import PostTypeChart from './components/post-type-chart.vue'
|
import PostTypeChart from './components/post-type-chart.vue'
|
||||||
import PostViewChart from './components/post-view-chart.vue'
|
import PostViewChart from './components/post-view-chart.vue'
|
||||||
@@ -25,22 +24,22 @@ const activeCollapseNames = ref(['1', '2'])
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
getDashboardDataApi().then((res) => {
|
// getDashboardDataApi().then((res) => {
|
||||||
if (res.isSuccess) {
|
// if (res.isSuccess) {
|
||||||
// dashboradData.value = res.data
|
// // dashboradData.value = res.data
|
||||||
dashboradData.value.typeChart = [...res.data.typeChart]
|
// dashboradData.value.typeChart = [...res.data.typeChart]
|
||||||
|
|
||||||
console.log(dashboradData.value)
|
// console.log(dashboradData.value)
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
ElMessage.error(res.message || '加载失败,请稍后再试')
|
// ElMessage.error(res.message || '加载失败,请稍后再试')
|
||||||
}
|
// }
|
||||||
}).catch((err) => {
|
// }).catch((err) => {
|
||||||
console.log(err)
|
// console.log(err)
|
||||||
ElMessage.error('加载失败,请稍后再试')
|
// ElMessage.error('加载失败,请稍后再试')
|
||||||
}).finally(() => {
|
// }).finally(() => {
|
||||||
loading.value = false
|
// loading.value = false
|
||||||
})
|
// })
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ watch(searchKey, async (val) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.right-view {
|
.right-view {
|
||||||
|
padding:0px 120px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ const activeCollapseNames = ref(['1', '2', '3'])
|
|||||||
:rules="formRules"
|
:rules="formRules"
|
||||||
label-width="auto"
|
label-width="auto"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
|
style="width: 700px;"
|
||||||
>
|
>
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
@@ -214,6 +215,7 @@ const activeCollapseNames = ref(['1', '2', '3'])
|
|||||||
:model="companyDetail"
|
:model="companyDetail"
|
||||||
:rules="formRules"
|
:rules="formRules"
|
||||||
label-width="auto"
|
label-width="auto"
|
||||||
|
style="width: 700px;"
|
||||||
>
|
>
|
||||||
<el-form-item prop="profile">
|
<el-form-item prop="profile">
|
||||||
<el-input v-model="companyDetail.profile" type="textarea" />
|
<el-input v-model="companyDetail.profile" type="textarea" />
|
||||||
@@ -284,9 +286,6 @@ const activeCollapseNames = ref(['1', '2', '3'])
|
|||||||
}
|
}
|
||||||
.form-footer {
|
.form-footer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.08);
|
|
||||||
position: sticky;
|
|
||||||
bottom: 0;
|
|
||||||
align-self: flex-end;
|
align-self: flex-end;
|
||||||
height: 56px;
|
height: 56px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type { CompanyUser, CompanyUserForm } from '@/types/company/user'
|
|||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
import EmailCodeInput from '@/components/EmailCodeInput.vue'
|
import EmailCodeInput from '@/components/EmailCodeInput.vue'
|
||||||
|
import ImageUploadCard from '@/components/ImageUploadCard.vue'
|
||||||
import { authCodeVerifyApi } from '@/request/api/auth/code'
|
import { authCodeVerifyApi } from '@/request/api/auth/code'
|
||||||
import { addCompanyUserApi, updateCompanyUserApi } from '@/request/api/company/user'
|
import { addCompanyUserApi, updateCompanyUserApi } from '@/request/api/company/user'
|
||||||
import { useUserStore } from '@/store/user'
|
import { useUserStore } from '@/store/user'
|
||||||
@@ -44,6 +45,7 @@ const form = ref<CompanyUserForm>({
|
|||||||
canuse: '1',
|
canuse: '1',
|
||||||
password: '',
|
password: '',
|
||||||
emailCode: '',
|
emailCode: '',
|
||||||
|
avatar: '',
|
||||||
})
|
})
|
||||||
watch(
|
watch(
|
||||||
() => props.user,
|
() => props.user,
|
||||||
@@ -172,6 +174,7 @@ async function handleSubmit(formEl: FormInstance | undefined) {
|
|||||||
position: form.value.position,
|
position: form.value.position,
|
||||||
phone: form.value.phone,
|
phone: form.value.phone,
|
||||||
canuse: form.value.canuse,
|
canuse: form.value.canuse,
|
||||||
|
avatar: form.value.avatar,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (response.isSuccess) {
|
if (response.isSuccess) {
|
||||||
@@ -220,6 +223,9 @@ async function handleSubmit(formEl: FormInstance | undefined) {
|
|||||||
label-width="auto"
|
label-width="auto"
|
||||||
label-position="right"
|
label-position="right"
|
||||||
>
|
>
|
||||||
|
<el-form-item label="头像" prop="name">
|
||||||
|
<ImageUploadCard v-model="form.avatar" :auto-upload-aliyun="true" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="名称" prop="name">
|
<el-form-item label="名称" prop="name">
|
||||||
<el-input v-model="form.name" />
|
<el-input v-model="form.name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { CompanyUser, QueryCompanyUserParams } from '@/types/company/user'
|
|||||||
import { Delete, Plus, Refresh, Search } from '@element-plus/icons-vue'
|
import { Delete, Plus, Refresh, Search } from '@element-plus/icons-vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { onMounted, reactive, ref } from 'vue'
|
import { onMounted, reactive, ref } from 'vue'
|
||||||
|
import SafeImage from '@/components/SafeImage.vue'
|
||||||
import { deleteCompanyUserApi, queryCompanyUserApi } from '@/request/api/company/user'
|
import { deleteCompanyUserApi, queryCompanyUserApi } from '@/request/api/company/user'
|
||||||
import { useUserStore } from '@/store/user'
|
import { useUserStore } from '@/store/user'
|
||||||
import EditDrawer from './components/EditDrawer.vue'
|
import EditDrawer from './components/EditDrawer.vue'
|
||||||
@@ -251,6 +252,13 @@ function handleDelteRows(val?: CompanyUser) {
|
|||||||
align="center"
|
align="center"
|
||||||
:selectable="selectable"
|
:selectable="selectable"
|
||||||
/>
|
/>
|
||||||
|
<el-table-column prop="avatar" label="头像" align="center" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<div style="display: flex;align-items: center;justify-content: center;">
|
||||||
|
<SafeImage :url="scope.row.avatar" :size="64" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="name" label="名称" align="center">
|
<el-table-column prop="name" label="名称" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<template v-if="scope.row.role === 1">
|
<template v-if="scope.row.role === 1">
|
||||||
|
|||||||
Reference in new issue
Block a user