更新部门管理后端功能代码

This commit is contained in:
user 2025-03-03 18:35:20 +08:00
parent aab2936255
commit c359796013
13 changed files with 514 additions and 94 deletions

View File

@ -61,7 +61,7 @@ MySQL数据库要求如下:
需要编写部门管理(jhi_depart表)的功能的后端API基本接口功能不需要DTO类
数据表都要包括有以下字段: id, company(与jhi_company.number对应所属公司), created_by, created_date, updated_by, updated_date, version(乐观锁,默认值为0),
有层次关系(number, parent_number), 还需要region字段(与jhi_region.number对应所属区域),
请按照 region模块的代码风格方式来写。
请按照 region模块的实现代码方式来写,确保系统风格的一致性
后端API基本接口功能
1. 新增部门信息 POST /api/departs
2. 修改部门信息 PUT /api/departs/{id}

View File

@ -19,7 +19,6 @@ import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.r2dbc.convert.MappingR2dbcConverter;
import org.springframework.data.r2dbc.convert.R2dbcCustomConversions;
//import org.springframework.data.r2dbc.mapping.R2dbcMappingContext;
import org.springframework.data.r2dbc.dialect.DialectResolver;
import org.springframework.data.r2dbc.dialect.R2dbcDialect;
import org.springframework.data.r2dbc.query.UpdateMapper;
@ -33,16 +32,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
public class DatabaseConfiguration {
//@Bean
//public R2dbcMappingContext r2dbcMappingContext(R2dbcCustomConversions customConversions) {
// R2dbcMappingContext mappingContext = new R2dbcMappingContext();
// mappingContext.setForceQuote(false);
// mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
// // 设置更新时忽略null值
// mappingContext.setNullHandling(NullHandling.IGNORE);
// return mappingContext;
//}
/**
* Simple singleton to convert {@link UUID}s to their {@link String} representation.
*/

View File

@ -5,6 +5,7 @@ import java.io.Serializable;
import java.time.Instant;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
@Table("jhi_company")
@ -27,10 +28,23 @@ public class Company extends AbstractAuditingEntity<Long> implements Serializabl
private String address;
@Size(max = 50)
@Column("license_no")
private String licenseNo;
@Column("license_expire")
private Instant licenseExpire;
@Size(max = 50)
@Column("contact_person")
private String contactPerson;
@Size(max = 20)
@Column("contact_phone")
private String contactPhone;
@Size(max = 500)
private String remark;
@Version
@NotNull
private Long version = 0L;
@ -84,6 +98,30 @@ public class Company extends AbstractAuditingEntity<Long> implements Serializabl
this.licenseExpire = licenseExpire;
}
public String getContactPerson() {
return contactPerson;
}
public void setContactPerson(String contactPerson) {
this.contactPerson = contactPerson;
}
public String getContactPhone() {
return contactPhone;
}
public void setContactPhone(String contactPhone) {
this.contactPhone = contactPhone;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Long getVersion() {
return version;
}
@ -112,6 +150,15 @@ public class Company extends AbstractAuditingEntity<Long> implements Serializabl
'\'' +
", licenseExpire=" +
licenseExpire +
", contactPerson='" +
contactPerson +
'\'' +
", contactPhone='" +
contactPhone +
'\'' +
", remark='" +
remark +
'\'' +
", createdBy='" +
getCreatedBy() +
'\'' +

View File

@ -0,0 +1,185 @@
package com.vxnet.pms.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.io.Serializable;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
/**
* A Depart.
*/
@Table("jhi_depart")
public class Depart extends AbstractAuditingEntity<Long> implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column("id")
private Long id;
@Column("number")
private String number;
@Column("parent_number")
private String parentNumber;
@Column("name")
private String name;
@Column("property")
private String property;
@Column("remark")
private String remark;
@Column("sort_no")
private Integer sortNo;
@Column("company")
private String company;
@Column("region")
private String region;
@Column("version")
private Integer version;
@org.springframework.data.annotation.Transient
private List<Depart> children;
@Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getParentNumber() {
return parentNumber;
}
public void setParentNumber(String parentNumber) {
this.parentNumber = parentNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Integer getSortNo() {
return sortNo;
}
public void setSortNo(Integer sortNo) {
this.sortNo = sortNo;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public List<Depart> getChildren() {
return children;
}
public void setChildren(List<Depart> children) {
this.children = children;
}
@Override
public String toString() {
return (
"Depart{" +
"id=" +
getId() +
", number='" +
getNumber() +
"'" +
", parentNumber='" +
getParentNumber() +
"'" +
", name='" +
getName() +
"'" +
", property='" +
getProperty() +
"'" +
", remark='" +
getRemark() +
"'" +
", sortNo=" +
getSortNo() +
", company='" +
getCompany() +
"'" +
", region='" +
getRegion() +
"'" +
", createdBy='" +
getCreatedBy() +
"'" +
", createdDate=" +
getCreatedDate() +
", updatedBy='" +
getUpdatedBy() +
"'" +
", updatedDate=" +
getUpdatedDate() +
", version=" +
getVersion() +
"}"
);
}
}

View File

@ -166,4 +166,56 @@ public class Region extends AbstractAuditingEntity<Long> implements Serializable
public void setVersion(Long version) {
this.version = version;
}
@Override
public String toString() {
return (
"Region{" +
"id=" +
id +
", number='" +
number +
"'" +
", parentNumber='" +
parentNumber +
"'" +
", name='" +
name +
"'" +
", company='" +
company +
"'" +
", address='" +
address +
"'" +
", contactPerson='" +
contactPerson +
"'" +
", contactPhone='" +
contactPhone +
"'" +
", email='" +
email +
"'" +
", contactAddress='" +
contactAddress +
"'" +
", remark='" +
remark +
"'" +
", createdBy='" +
getCreatedBy() +
"'" +
", createdDate=" +
getCreatedDate() +
", updatedBy='" +
getUpdatedBy() +
"'" +
", updatedDate=" +
getUpdatedDate() +
", version=" +
version +
"}"
);
}
}

View File

@ -0,0 +1,34 @@
package com.vxnet.pms.repository;
import com.vxnet.pms.domain.Depart;
import org.springframework.data.domain.Pageable;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
import org.springframework.data.repository.query.Param;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* Spring Data R2DBC repository for the Depart entity.
*/
public interface DepartRepository extends R2dbcRepository<Depart, Long> {
@Query("SELECT * FROM jhi_depart WHERE IFNULL(parent_number, '') = ''")
Flux<Depart> findRootDeparts();
@Query("SELECT * FROM jhi_depart WHERE parent_number = :parentNumber")
Flux<Depart> findByParentNumber(@Param("parentNumber") String parentNumber);
@Query("SELECT COUNT(*) FROM jhi_depart WHERE parent_number = :parentNumber")
Mono<Long> countByParentNumber(@Param("parentNumber") String parentNumber);
@Query(
"SELECT * FROM jhi_depart ORDER BY :#{#pageable.sort.toString().replace(':', ' ')} LIMIT :#{#pageable.pageSize} OFFSET :#{#pageable.offset}"
)
Flux<Depart> findAll(Pageable pageable);
@Query("SELECT * FROM jhi_depart WHERE number = :number")
Mono<Depart> findByNumber(@Param("number") String number);
@Query("DELETE FROM jhi_depart WHERE number = :number")
Mono<Void> deleteByNumber(@Param("number") String number);
}

View File

@ -31,58 +31,49 @@ public class CompanyService {
@Transactional
public Mono<Company> save(Company company) {
log.info("Saving Company with id: {} and name: {}", company.getId(), company.getName());
if (company.getId() == null) {
company.setVersion(null);
} else {
log.info("Update Company with created by: {} and created date: {}", company.getCreatedBy(), company.getCreatedDate());
}
return companyRepository
.save(company)
.doOnSuccess(savedCompany -> log.info("Company saved successfully with id: {}", savedCompany.getId()))
.doOnError(error -> log.error("Error saving Company: {}", error.getMessage()));
return companyRepository.save(company);
}
@Transactional
public Mono<Company> createCompany(Company company) {
company.setVersion(null);
return save(company);
}
@Transactional
public Mono<Company> updateCompany(Long id, Company company) {
company.setId(id);
return save(company);
return companyRepository
.findByIdWithTableName(id)
.flatMap(existingCompany -> {
existingCompany.setName(company.getName());
existingCompany.setAddress(company.getAddress());
existingCompany.setLicenseNo(company.getLicenseNo());
existingCompany.setLicenseExpire(company.getLicenseExpire());
existingCompany.setContactPerson(company.getContactPerson());
existingCompany.setContactPhone(company.getContactPhone());
existingCompany.setRemark(company.getRemark());
return save(existingCompany);
});
}
@Transactional(readOnly = true)
public Flux<Company> getAllCompanies() {
return companyRepository
.findAllCompanies()
.doOnComplete(() -> log.info("Successfully retrieved all companies"))
.doOnError(error -> log.error("Error retrieving companies: {}", error.getMessage()));
return companyRepository.findAllCompanies();
}
@Transactional
public Mono<Void> deleteCompany(Long id) {
return companyRepository
.deleteByIdWithTableName(id)
.doOnSuccess(result -> log.info("Successfully deleted Company with id: {}", id))
.doOnError(error -> log.error("Error deleting Company with id {}: {}", id, error.getMessage()));
return companyRepository.deleteByIdWithTableName(id);
}
@Transactional(readOnly = true)
public Flux<Company> searchCompanies(String keyword, Pageable pageable) {
return companyRepository
.searchCompanies(keyword, pageable)
.doOnComplete(() -> log.info("Successfully searched companies with keyword: {}", keyword))
.doOnError(error -> log.error("Error searching companies: {}", error.getMessage()));
return companyRepository.searchCompanies(keyword, pageable);
}
@Transactional(readOnly = true)
public Flux<Company> getActiveCompanies() {
return companyRepository
.findActiveCompanies()
.doOnComplete(() -> log.info("Successfully retrieved active companies"))
.doOnError(error -> log.error("Error retrieving active companies: {}", error.getMessage()));
return companyRepository.findActiveCompanies();
}
/**
@ -93,10 +84,7 @@ public class CompanyService {
*/
@Transactional(readOnly = true)
public Flux<Company> findAll(Pageable pageable) {
return companyRepository
.findAllWithSort(pageable)
.doOnComplete(() -> log.info("Successfully retrieved all companies"))
.doOnError(error -> log.error("Error retrieving companies: {}", error.getMessage()));
return companyRepository.findAllWithSort(pageable);
}
/**
@ -107,16 +95,7 @@ public class CompanyService {
*/
@Transactional(readOnly = true)
public Mono<Company> findOne(Long id) {
return companyRepository
.findByIdWithTableName(id)
.doOnSuccess(company -> {
if (company != null) {
log.info("Found Company with id: {} and name: {}", id, company.getName());
} else {
log.info("No Company found with id: {}", id);
}
})
.doOnError(error -> log.error("Error finding Company with id {}: {}", id, error.getMessage()));
return companyRepository.findByIdWithTableName(id);
}
@Transactional(readOnly = true)

View File

@ -0,0 +1,97 @@
package com.vxnet.pms.service;
import com.vxnet.pms.domain.Depart;
import com.vxnet.pms.repository.DepartRepository;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Service
public class DepartService {
private final DepartRepository departRepository;
public DepartService(DepartRepository departRepository) {
this.departRepository = departRepository;
}
public Mono<Depart> createDepart(Depart depart) {
depart.setVersion(0);
return departRepository.save(depart);
}
public Mono<Depart> updateDepart(Long id, Depart depart) {
return departRepository
.findById(id)
.flatMap(existingDepart -> {
existingDepart.setNumber(depart.getNumber());
existingDepart.setName(depart.getName());
existingDepart.setParentNumber(depart.getParentNumber());
existingDepart.setCompany(depart.getCompany());
existingDepart.setRegion(depart.getRegion());
existingDepart.setProperty(depart.getProperty());
existingDepart.setRemark(depart.getRemark());
existingDepart.setSortNo(depart.getSortNo());
return departRepository.save(existingDepart);
});
}
public Mono<Void> deleteDepart(String number) {
return departRepository
.countByParentNumber(number)
.flatMap(count -> {
if (count > 0) {
return Mono.error(new IllegalStateException("Cannot delete department with children"));
}
return departRepository.deleteByNumber(number);
});
}
public Mono<Depart> getDepart(String number) {
return departRepository.findByNumber(number);
}
public Flux<Depart> getAllDeparts(Pageable pageable) {
return departRepository.findAll(pageable);
}
public Flux<Depart> getDepartTree() {
return departRepository
.findRootDeparts()
.flatMap(rootDepart ->
Mono.just(rootDepart)
.zipWith(getChildren(rootDepart.getNumber()).collectList())
.map(tuple -> {
rootDepart.setChildren(tuple.getT2());
return rootDepart;
})
);
}
public Mono<Depart> getDepartTree(String number) {
return departRepository
.findByNumber(number)
.flatMap(depart ->
Mono.just(depart)
.zipWith(getChildren(depart.getNumber()).collectList())
.map(tuple -> {
depart.setChildren(tuple.getT2());
return depart;
})
);
}
private Flux<Depart> getChildren(String parentNumber) {
return departRepository
.findByParentNumber(parentNumber)
.flatMap(depart ->
Mono.just(depart)
.zipWith(getChildren(depart.getNumber()).collectList())
.map(tuple -> {
depart.setChildren(tuple.getT2());
return depart;
})
);
}
}

View File

@ -2,8 +2,6 @@ package com.vxnet.pms.service;
import com.vxnet.pms.domain.Region;
import com.vxnet.pms.repository.RegionRepository;
import com.vxnet.pms.security.SecurityUtils;
import java.time.Instant;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -21,38 +19,25 @@ public class RegionService {
}
public Mono<Region> createRegion(Region region) {
region.setCreatedDate(Instant.now());
region.setUpdatedDate(Instant.now());
region.setVersion(null);
return SecurityUtils.getCurrentUserLogin()
.map(username -> {
region.setCreatedBy(username);
region.setUpdatedBy(username);
return region;
})
.flatMap(regionRepository::save);
return regionRepository.save(region);
}
public Mono<Region> updateRegion(Long id, Region region) {
return SecurityUtils.getCurrentUserLogin()
.flatMap(username ->
regionRepository
.findById(id)
.flatMap(existingRegion -> {
existingRegion.setNumber(region.getNumber());
existingRegion.setName(region.getName());
existingRegion.setParentNumber(region.getParentNumber());
existingRegion.setCompany(region.getCompany());
existingRegion.setAddress(region.getAddress());
existingRegion.setContactPerson(region.getContactPerson());
existingRegion.setContactPhone(region.getContactPhone());
existingRegion.setEmail(region.getEmail());
existingRegion.setRemark(region.getRemark());
existingRegion.setUpdatedDate(Instant.now());
existingRegion.setUpdatedBy(username);
return regionRepository.save(existingRegion);
})
);
return regionRepository
.findById(id)
.flatMap(existingRegion -> {
existingRegion.setNumber(region.getNumber());
existingRegion.setName(region.getName());
existingRegion.setParentNumber(region.getParentNumber());
existingRegion.setCompany(region.getCompany());
existingRegion.setAddress(region.getAddress());
existingRegion.setContactPerson(region.getContactPerson());
existingRegion.setContactPhone(region.getContactPhone());
existingRegion.setEmail(region.getEmail());
existingRegion.setRemark(region.getRemark());
return regionRepository.save(existingRegion);
});
}
public Mono<Void> deleteRegion(String number) {

View File

@ -41,7 +41,6 @@ public class CompanyResource {
@PostMapping("/companies")
public Mono<ResponseEntity<Company>> createCompany(@Valid @RequestBody Company company) {
log.debug("REST request to save Company : {}", company);
log.info("Processing create request for Company with name: {}", company.getName());
return companyService
.createCompany(company)
.map(result -> {
@ -66,13 +65,7 @@ public class CompanyResource {
@PutMapping("/companies/{id}")
public Mono<ResponseEntity<Company>> updateCompany(@PathVariable(value = "id") final Long id, @Valid @RequestBody Company company) {
log.debug("REST request to update Company : {}, {}", id, company);
return companyService
.updateCompany(id, company)
.map(result -> {
log.info("Company updated successfully with id: {}", result.getId());
return ResponseEntity.ok().body(result);
})
.doOnError(error -> log.error("Error in REST layer while updating Company: {}", error.getMessage()));
return companyService.updateCompany(id, company).map(result -> ResponseEntity.ok().body(result));
}
/**

View File

@ -0,0 +1,53 @@
package com.vxnet.pms.web.rest;
import com.vxnet.pms.domain.Depart;
import com.vxnet.pms.service.DepartService;
import java.net.URI;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping("/api")
public class DepartResource {
private final DepartService departService;
public DepartResource(DepartService departService) {
this.departService = departService;
}
@PostMapping("/departs")
public Mono<ResponseEntity<Depart>> createDepart(@RequestBody Depart depart) {
return departService
.createDepart(depart)
.map(result -> ResponseEntity.created(URI.create("/api/departs/" + result.getId())).body(result));
}
@PutMapping("/departs/{id}")
public Mono<ResponseEntity<Depart>> updateDepart(@PathVariable(value = "id") final Long id, @RequestBody Depart depart) {
return departService.updateDepart(id, depart).map(result -> ResponseEntity.ok().body(result));
}
@DeleteMapping("/departs/{number}")
public Mono<ResponseEntity<Void>> deleteDepart(@PathVariable String number) {
return departService.deleteDepart(number).then(Mono.just(ResponseEntity.noContent().build()));
}
@GetMapping("/departs/{number}")
public Mono<ResponseEntity<Depart>> getDepart(@PathVariable String number) {
return departService.getDepartTree(number).map(depart -> ResponseEntity.ok().body(depart));
}
@GetMapping("/departs")
public Mono<ResponseEntity<Flux<Depart>>> getAllDeparts(Pageable pageable) {
return Mono.just(ResponseEntity.ok().body(departService.getAllDeparts(pageable)));
}
@GetMapping("/departs/tree")
public Mono<ResponseEntity<Flux<Depart>>> getDepartTree() {
return Mono.just(ResponseEntity.ok().body(departService.getDepartTree()));
}
}

View File

@ -20,6 +20,9 @@
<column name="address" type="varchar(200)" remarks="公司地址"/>
<column name="license_no" type="varchar(50)" remarks="营业执照号码"/>
<column name="license_expire" type="timestamp" remarks="营业执照到期日期"/>
<column name="contact_person" type="varchar(50)" remarks="联系人"/>
<column name="contact_phone" type="varchar(20)" remarks="联系电话"/>
<column name="remark" type="varchar(500)" remarks="备注"/>
<column name="created_by" type="varchar(50)" remarks="创建人"/>
<column name="created_date" type="timestamp" remarks="创建时间"/>
<column name="updated_by" type="varchar(50)" remarks="修改人"/>
@ -39,6 +42,9 @@
<column name="address" type="string"/>
<column name="license_no" type="string"/>
<column name="license_expire" type="timestamp"/>
<column name="contact_person" type="string"/>
<column name="contact_phone" type="string"/>
<column name="remark" type="string"/>
<column name="created_by" type="string"/>
<column name="created_date" type="timestamp"/>
<column name="updated_by" type="string"/>

View File

@ -1,3 +1,3 @@
id;number;name;address;license_no;license_expire;created_by;created_date;updated_by;updated_date;version
1;COM001;测试公司;广州市天河区天河路100号;GZ202403250001;2025-03-25 00:00:00;system;2024-03-25 00:00:00;system;2024-03-25 00:00:00;0
2;COM002;示例企业;深圳市南山区科技园;SZ202403250002;2025-03-25 00:00:00;system;2024-03-25 00:00:00;system;2024-03-25 00:00:00;0
id;number;name;address;license_no;license_expire;contact_person;contact_phone;remark;created_by;created_date;updated_by;updated_date;version
1;COM001;测试公司;广州市天河区天河路100号;GZ202403250001;2025-03-25 00:00:00;张三;13800138001;测试公司备注信息;system;2024-03-25 00:00:00;system;2024-03-25 00:00:00;0
2;COM002;示例企业;深圳市南山区科技园;SZ202403250002;2025-03-25 00:00:00;李四;13800138002;示例企业备注信息;system;2024-03-25 00:00:00;system;2024-03-25 00:00:00;0
1 id number name address license_no license_expire contact_person contact_phone remark created_by created_date updated_by updated_date version
2 1 COM001 测试公司 广州市天河区天河路100号 GZ202403250001 2025-03-25 00:00:00 张三 13800138001 测试公司备注信息 system 2024-03-25 00:00:00 system 2024-03-25 00:00:00 0
3 2 COM002 示例企业 深圳市南山区科技园 SZ202403250002 2025-03-25 00:00:00 李四 13800138002 示例企业备注信息 system 2024-03-25 00:00:00 system 2024-03-25 00:00:00 0