feat: add community content and address APIs

This commit is contained in:
王鹏
2026-07-07 15:24:14 +08:00
parent 51e0f3a5ad
commit cad4bd3ea1
17 changed files with 1206 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
package com.linhelp.community;
import com.linhelp.common.api.ApiResponse;
import com.linhelp.common.security.RequireRole;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CommunityController {
private final CommunityService communityService;
public CommunityController(CommunityService communityService) {
this.communityService = communityService;
}
@GetMapping("/api/mini/community")
public ApiResponse<CommunityResponse> miniCurrent() {
return ApiResponse.ok(communityService.currentCommunity());
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@GetMapping("/api/admin/community")
public ApiResponse<CommunityResponse> adminCurrent() {
return ApiResponse.ok(communityService.currentCommunity());
}
}

View File

@@ -0,0 +1,69 @@
package com.linhelp.community;
import java.util.Map;
public class CommunityResponse {
private Long id;
private Long tenantId;
private String name;
private String address;
private String contactName;
private String contactPhone;
private Map<String, Boolean> modules;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public String getContactPhone() {
return contactPhone;
}
public void setContactPhone(String contactPhone) {
this.contactPhone = contactPhone;
}
public Map<String, Boolean> getModules() {
return modules;
}
public void setModules(Map<String, Boolean> modules) {
this.modules = modules;
}
}

View File

@@ -0,0 +1,32 @@
package com.linhelp.community;
import org.springframework.stereotype.Service;
import java.util.LinkedHashMap;
import java.util.Map;
@Service
public class CommunityService {
public CommunityResponse currentCommunity() {
CommunityResponse response = new CommunityResponse();
response.setId(1L);
response.setTenantId(1L);
response.setName("邻小帮示范小区");
response.setAddress("示范路 1 号");
response.setContactName("社区管理员");
response.setContactPhone("13800000000");
response.setModules(defaultModules());
return response;
}
private Map<String, Boolean> defaultModules() {
Map<String, Boolean> modules = new LinkedHashMap<String, Boolean>();
modules.put("GOODS", true);
modules.put("EXPRESS", true);
modules.put("GROUP_BUY", true);
modules.put("SECOND_HAND", true);
modules.put("NOTICE", true);
return modules;
}
}

View File

@@ -0,0 +1,64 @@
package com.linhelp.notice;
import com.linhelp.common.api.ApiResponse;
import com.linhelp.common.security.AuthService;
import com.linhelp.common.security.CurrentUser;
import com.linhelp.common.security.RequireRole;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@RestController
public class BannerController {
private final BannerService bannerService;
private final AuthService authService;
public BannerController(BannerService bannerService, AuthService authService) {
this.bannerService = bannerService;
this.authService = authService;
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@GetMapping("/api/admin/banners")
public ApiResponse<List<BannerResponse>> adminList() {
CurrentUser user = authService.currentUser();
return ApiResponse.ok(bannerService.listAdmin(user.getCommunityId()));
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@PostMapping("/api/admin/banners")
public ApiResponse<BannerResponse> create(@Valid @RequestBody BannerRequest request) {
CurrentUser user = authService.currentUser();
request.setTenantId(user.getTenantId());
request.setCommunityId(user.getCommunityId());
return ApiResponse.ok(bannerService.create(request));
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@PutMapping("/api/admin/banners/{id}")
public ApiResponse<BannerResponse> update(@PathVariable Long id, @Valid @RequestBody BannerRequest request) {
CurrentUser user = authService.currentUser();
request.setTenantId(user.getTenantId());
request.setCommunityId(user.getCommunityId());
return ApiResponse.ok(bannerService.update(id, request));
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@DeleteMapping("/api/admin/banners/{id}")
public ApiResponse<Void> delete(@PathVariable Long id) {
bannerService.delete(id);
return ApiResponse.ok();
}
@GetMapping("/api/mini/banners")
public ApiResponse<List<BannerResponse>> miniList() {
return ApiResponse.ok(bannerService.listEnabled(1L));
}
}

View File

@@ -0,0 +1,83 @@
package com.linhelp.notice;
import javax.validation.constraints.NotBlank;
public class BannerRequest {
private Long tenantId;
private Long communityId;
@NotBlank
private String title;
@NotBlank
private String imageUrl;
private String linkType;
private String linkValue;
private int sortNo;
private boolean enabled = true;
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public Long getCommunityId() {
return communityId;
}
public void setCommunityId(Long communityId) {
this.communityId = communityId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getLinkType() {
return linkType;
}
public void setLinkType(String linkType) {
this.linkType = linkType;
}
public String getLinkValue() {
return linkValue;
}
public void setLinkValue(String linkValue) {
this.linkValue = linkValue;
}
public int getSortNo() {
return sortNo;
}
public void setSortNo(int sortNo) {
this.sortNo = sortNo;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

View File

@@ -0,0 +1,85 @@
package com.linhelp.notice;
public class BannerResponse {
private Long id;
private Long tenantId;
private Long communityId;
private String title;
private String imageUrl;
private String linkType;
private String linkValue;
private int sortNo;
private boolean enabled;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public Long getCommunityId() {
return communityId;
}
public void setCommunityId(Long communityId) {
this.communityId = communityId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getLinkType() {
return linkType;
}
public void setLinkType(String linkType) {
this.linkType = linkType;
}
public String getLinkValue() {
return linkValue;
}
public void setLinkValue(String linkValue) {
this.linkValue = linkValue;
}
public int getSortNo() {
return sortNo;
}
public void setSortNo(int sortNo) {
this.sortNo = sortNo;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

View File

@@ -0,0 +1,81 @@
package com.linhelp.notice;
import com.linhelp.common.exception.BizException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
@Service
public class BannerService {
private final AtomicLong ids = new AtomicLong(1L);
private final Map<Long, BannerResponse> banners = new LinkedHashMap<Long, BannerResponse>();
public synchronized BannerResponse create(BannerRequest request) {
BannerResponse banner = new BannerResponse();
banner.setId(ids.getAndIncrement());
copy(request, banner);
banners.put(banner.getId(), banner);
return banner;
}
public synchronized List<BannerResponse> listAdmin(Long communityId) {
List<BannerResponse> result = new ArrayList<BannerResponse>();
for (BannerResponse banner : banners.values()) {
if (communityId.equals(banner.getCommunityId())) {
result.add(banner);
}
}
return result;
}
public synchronized List<BannerResponse> listEnabled(Long communityId) {
List<BannerResponse> result = new ArrayList<BannerResponse>();
for (BannerResponse banner : banners.values()) {
if (communityId.equals(banner.getCommunityId()) && banner.isEnabled()) {
result.add(banner);
}
}
Collections.sort(result, new Comparator<BannerResponse>() {
@Override
public int compare(BannerResponse left, BannerResponse right) {
return Integer.compare(left.getSortNo(), right.getSortNo());
}
});
return result;
}
public synchronized BannerResponse update(Long id, BannerRequest request) {
BannerResponse banner = require(id);
copy(request, banner);
return banner;
}
public synchronized void delete(Long id) {
banners.remove(id);
}
private BannerResponse require(Long id) {
BannerResponse banner = banners.get(id);
if (banner == null) {
throw new BizException(404, "Banner不存在");
}
return banner;
}
private void copy(BannerRequest request, BannerResponse banner) {
banner.setTenantId(request.getTenantId());
banner.setCommunityId(request.getCommunityId());
banner.setTitle(request.getTitle());
banner.setImageUrl(request.getImageUrl());
banner.setLinkType(request.getLinkType());
banner.setLinkValue(request.getLinkValue());
banner.setSortNo(request.getSortNo());
banner.setEnabled(request.isEnabled());
}
}

View File

@@ -0,0 +1,79 @@
package com.linhelp.notice;
import com.linhelp.common.api.ApiResponse;
import com.linhelp.common.security.AuthService;
import com.linhelp.common.security.CurrentUser;
import com.linhelp.common.security.RequireRole;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@RestController
public class NoticeController {
private final NoticeService noticeService;
private final AuthService authService;
public NoticeController(NoticeService noticeService, AuthService authService) {
this.noticeService = noticeService;
this.authService = authService;
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@GetMapping("/api/admin/notices")
public ApiResponse<List<NoticeResponse>> adminList() {
CurrentUser user = authService.currentUser();
return ApiResponse.ok(noticeService.listAdmin(user.getCommunityId()));
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@PostMapping("/api/admin/notices")
public ApiResponse<NoticeResponse> create(@Valid @RequestBody NoticeRequest request) {
CurrentUser user = authService.currentUser();
request.setTenantId(user.getTenantId());
request.setCommunityId(user.getCommunityId());
return ApiResponse.ok(noticeService.create(request));
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@PutMapping("/api/admin/notices/{id}")
public ApiResponse<NoticeResponse> update(@PathVariable Long id, @Valid @RequestBody NoticeRequest request) {
return ApiResponse.ok(noticeService.update(id, request));
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@PutMapping("/api/admin/notices/{id}/publish")
public ApiResponse<NoticeResponse> publish(@PathVariable Long id) {
return ApiResponse.ok(noticeService.publish(id));
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@PutMapping("/api/admin/notices/{id}/offline")
public ApiResponse<NoticeResponse> offline(@PathVariable Long id) {
return ApiResponse.ok(noticeService.offline(id));
}
@RequireRole({"PLATFORM_ADMIN", "COMMUNITY_ADMIN"})
@DeleteMapping("/api/admin/notices/{id}")
public ApiResponse<Void> delete(@PathVariable Long id) {
noticeService.delete(id);
return ApiResponse.ok();
}
@GetMapping("/api/mini/notices")
public ApiResponse<List<NoticeResponse>> miniList() {
return ApiResponse.ok(noticeService.listPublished(1L));
}
@GetMapping("/api/mini/notices/{id}")
public ApiResponse<NoticeResponse> miniDetail(@PathVariable Long id) {
return ApiResponse.ok(noticeService.detail(id));
}
}

View File

@@ -0,0 +1,67 @@
package com.linhelp.notice;
import javax.validation.constraints.NotBlank;
public class NoticeRequest {
private Long tenantId;
private Long communityId;
@NotBlank
private String title;
@NotBlank
private String content;
@NotBlank
private String category;
private boolean pinned;
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public Long getCommunityId() {
return communityId;
}
public void setCommunityId(Long communityId) {
this.communityId = communityId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public boolean isPinned() {
return pinned;
}
public void setPinned(boolean pinned) {
this.pinned = pinned;
}
}

View File

@@ -0,0 +1,87 @@
package com.linhelp.notice;
import java.time.LocalDateTime;
public class NoticeResponse {
private Long id;
private Long tenantId;
private Long communityId;
private String title;
private String content;
private String category;
private boolean pinned;
private String status;
private LocalDateTime publishedAt;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public Long getCommunityId() {
return communityId;
}
public void setCommunityId(Long communityId) {
this.communityId = communityId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public boolean isPinned() {
return pinned;
}
public void setPinned(boolean pinned) {
this.pinned = pinned;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public LocalDateTime getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(LocalDateTime publishedAt) {
this.publishedAt = publishedAt;
}
}

View File

@@ -0,0 +1,122 @@
package com.linhelp.notice;
import com.linhelp.common.exception.BizException;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
@Service
public class NoticeService {
public static final String STATUS_DRAFT = "DRAFT";
public static final String STATUS_PUBLISHED = "PUBLISHED";
public static final String STATUS_OFFLINE = "OFFLINE";
private final AtomicLong ids = new AtomicLong(1L);
private final Map<Long, NoticeResponse> notices = new LinkedHashMap<Long, NoticeResponse>();
public synchronized NoticeResponse create(NoticeRequest request) {
NoticeResponse notice = new NoticeResponse();
notice.setId(ids.getAndIncrement());
notice.setTenantId(request.getTenantId());
notice.setCommunityId(request.getCommunityId());
copy(request, notice);
notice.setStatus(STATUS_DRAFT);
notices.put(notice.getId(), notice);
return notice;
}
public synchronized List<NoticeResponse> listAdmin(Long communityId) {
List<NoticeResponse> result = new ArrayList<NoticeResponse>();
for (NoticeResponse notice : notices.values()) {
if (communityId.equals(notice.getCommunityId())) {
result.add(notice);
}
}
return result;
}
public synchronized NoticeResponse update(Long id, NoticeRequest request) {
NoticeResponse notice = require(id);
copy(request, notice);
return notice;
}
public synchronized NoticeResponse publish(Long id) {
NoticeResponse notice = require(id);
notice.setStatus(STATUS_PUBLISHED);
notice.setPublishedAt(LocalDateTime.now());
return notice;
}
public synchronized NoticeResponse offline(Long id) {
NoticeResponse notice = require(id);
notice.setStatus(STATUS_OFFLINE);
return notice;
}
public synchronized void delete(Long id) {
notices.remove(id);
}
public synchronized NoticeResponse detail(Long id) {
return require(id);
}
public synchronized List<NoticeResponse> listPublished(Long communityId) {
List<NoticeResponse> result = new ArrayList<NoticeResponse>();
for (NoticeResponse notice : notices.values()) {
if (communityId.equals(notice.getCommunityId()) && STATUS_PUBLISHED.equals(notice.getStatus())) {
result.add(notice);
}
}
Collections.sort(result, new Comparator<NoticeResponse>() {
@Override
public int compare(NoticeResponse left, NoticeResponse right) {
if (left.isPinned() != right.isPinned()) {
return left.isPinned() ? -1 : 1;
}
LocalDateTime leftTime = left.getPublishedAt();
LocalDateTime rightTime = right.getPublishedAt();
if (leftTime == null && rightTime == null) {
return 0;
}
if (leftTime == null) {
return 1;
}
if (rightTime == null) {
return -1;
}
return rightTime.compareTo(leftTime);
}
});
return result;
}
private NoticeResponse require(Long id) {
NoticeResponse notice = notices.get(id);
if (notice == null) {
throw new BizException(404, "公告不存在");
}
return notice;
}
private void copy(NoticeRequest request, NoticeResponse notice) {
notice.setTitle(request.getTitle());
notice.setContent(request.getContent());
notice.setCategory(request.getCategory());
notice.setPinned(request.isPinned());
if (request.getTenantId() != null) {
notice.setTenantId(request.getTenantId());
}
if (request.getCommunityId() != null) {
notice.setCommunityId(request.getCommunityId());
}
}
}

View File

@@ -0,0 +1,98 @@
package com.linhelp.user;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public class AddressRequest {
private Long tenantId;
private Long communityId;
@NotBlank
private String contactName;
@NotBlank
private String phone;
@NotBlank
private String building;
@NotBlank
private String room;
private String detail;
private boolean defaultAddress;
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public Long getCommunityId() {
return communityId;
}
public void setCommunityId(Long communityId) {
this.communityId = communityId;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getBuilding() {
return building;
}
public void setBuilding(String building) {
this.building = building;
}
public String getRoom() {
return room;
}
public void setRoom(String room) {
this.room = room;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public boolean isDefault() {
return defaultAddress;
}
public void setDefault(boolean defaultAddress) {
this.defaultAddress = defaultAddress;
}
@NotNull
public Long requireTenantId(Long fallback) {
return tenantId == null ? fallback : tenantId;
}
@NotNull
public Long requireCommunityId(Long fallback) {
return communityId == null ? fallback : communityId;
}
}

View File

@@ -0,0 +1,94 @@
package com.linhelp.user;
public class AddressResponse {
private Long id;
private Long tenantId;
private Long communityId;
private Long userId;
private String contactName;
private String phone;
private String building;
private String room;
private String detail;
private boolean defaultAddress;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTenantId() {
return tenantId;
}
public void setTenantId(Long tenantId) {
this.tenantId = tenantId;
}
public Long getCommunityId() {
return communityId;
}
public void setCommunityId(Long communityId) {
this.communityId = communityId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getBuilding() {
return building;
}
public void setBuilding(String building) {
this.building = building;
}
public String getRoom() {
return room;
}
public void setRoom(String room) {
this.room = room;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public boolean isDefault() {
return defaultAddress;
}
public void setDefault(boolean defaultAddress) {
this.defaultAddress = defaultAddress;
}
}

View File

@@ -0,0 +1,61 @@
package com.linhelp.user;
import com.linhelp.common.api.ApiResponse;
import com.linhelp.common.security.AuthService;
import com.linhelp.common.security.CurrentUser;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/api/mini/addresses")
public class UserAddressController {
private final UserAddressService addressService;
private final AuthService authService;
public UserAddressController(UserAddressService addressService, AuthService authService) {
this.addressService = addressService;
this.authService = authService;
}
@GetMapping
public ApiResponse<List<AddressResponse>> listMine() {
CurrentUser user = authService.currentUser();
return ApiResponse.ok(addressService.listMine(user.getUserId()));
}
@PostMapping
public ApiResponse<AddressResponse> create(@Valid @RequestBody AddressRequest request) {
CurrentUser user = authService.currentUser();
request.setTenantId(request.requireTenantId(user.getTenantId()));
request.setCommunityId(request.requireCommunityId(user.getCommunityId()));
return ApiResponse.ok(addressService.create(user.getUserId(), request));
}
@PutMapping("/{id}")
public ApiResponse<AddressResponse> update(@PathVariable Long id, @Valid @RequestBody AddressRequest request) {
CurrentUser user = authService.currentUser();
return ApiResponse.ok(addressService.update(user.getUserId(), id, request));
}
@DeleteMapping("/{id}")
public ApiResponse<Void> delete(@PathVariable Long id) {
CurrentUser user = authService.currentUser();
addressService.delete(user.getUserId(), id);
return ApiResponse.ok();
}
@PutMapping("/{id}/default")
public ApiResponse<AddressResponse> setDefault(@PathVariable Long id) {
CurrentUser user = authService.currentUser();
return ApiResponse.ok(addressService.setDefault(user.getUserId(), id));
}
}

View File

@@ -0,0 +1,87 @@
package com.linhelp.user;
import com.linhelp.common.exception.BizException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
@Service
public class UserAddressService {
private final AtomicLong ids = new AtomicLong(1L);
private final Map<Long, AddressResponse> addresses = new LinkedHashMap<Long, AddressResponse>();
public synchronized AddressResponse create(Long userId, AddressRequest request) {
AddressResponse response = new AddressResponse();
response.setId(ids.getAndIncrement());
response.setTenantId(request.getTenantId());
response.setCommunityId(request.getCommunityId());
response.setUserId(userId);
copy(request, response);
if (request.isDefault()) {
clearDefaults(userId);
response.setDefault(true);
}
addresses.put(response.getId(), response);
return response;
}
public synchronized List<AddressResponse> listMine(Long userId) {
List<AddressResponse> result = new ArrayList<AddressResponse>();
for (AddressResponse address : addresses.values()) {
if (userId.equals(address.getUserId())) {
result.add(address);
}
}
return result;
}
public synchronized AddressResponse update(Long userId, Long id, AddressRequest request) {
AddressResponse address = requireMine(userId, id);
copy(request, address);
if (request.isDefault()) {
clearDefaults(userId);
address.setDefault(true);
}
return address;
}
public synchronized void delete(Long userId, Long id) {
requireMine(userId, id);
addresses.remove(id);
}
public synchronized AddressResponse setDefault(Long userId, Long id) {
AddressResponse address = requireMine(userId, id);
clearDefaults(userId);
address.setDefault(true);
return address;
}
private void clearDefaults(Long userId) {
for (AddressResponse address : addresses.values()) {
if (userId.equals(address.getUserId())) {
address.setDefault(false);
}
}
}
private AddressResponse requireMine(Long userId, Long id) {
AddressResponse address = addresses.get(id);
if (address == null || !userId.equals(address.getUserId())) {
throw new BizException(404, "地址不存在");
}
return address;
}
private void copy(AddressRequest request, AddressResponse response) {
response.setContactName(request.getContactName());
response.setPhone(request.getPhone());
response.setBuilding(request.getBuilding());
response.setRoom(request.getRoom());
response.setDetail(request.getDetail());
}
}

View File

@@ -0,0 +1,37 @@
package com.linhelp.notice;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class NoticeServiceTests {
@Test
void miniListOnlyContainsPublishedNoticesWithPinnedFirst() {
NoticeService noticeService = new NoticeService();
NoticeResponse normal = noticeService.create(request("普通公告", false));
NoticeResponse pinned = noticeService.create(request("置顶公告", true));
noticeService.create(request("草稿公告", false));
noticeService.publish(normal.getId());
noticeService.publish(pinned.getId());
List<NoticeResponse> notices = noticeService.listPublished(1L);
assertThat(notices).extracting(NoticeResponse::getTitle)
.containsExactly("置顶公告", "普通公告");
}
private NoticeRequest request(String title, boolean pinned) {
NoticeRequest request = new NoticeRequest();
request.setTenantId(1L);
request.setCommunityId(1L);
request.setTitle(title);
request.setContent(title + "内容");
request.setCategory("物业通知");
request.setPinned(pinned);
return request;
}
}

View File

@@ -0,0 +1,34 @@
package com.linhelp.user;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class UserAddressServiceTests {
@Test
void settingOneAddressAsDefaultClearsOtherDefaultsForSameUser() {
UserAddressService addressService = new UserAddressService();
addressService.create(1L, request("张三", "13800000000", "1栋", "101", true));
AddressResponse second = addressService.create(1L, request("张三", "13800000000", "1栋", "102", true));
List<AddressResponse> addresses = addressService.listMine(1L);
assertThat(addresses).filteredOn(AddressResponse::isDefault).singleElement()
.extracting(AddressResponse::getId).isEqualTo(second.getId());
}
private AddressRequest request(String contactName, String phone, String building, String room, boolean isDefault) {
AddressRequest request = new AddressRequest();
request.setTenantId(1L);
request.setCommunityId(1L);
request.setContactName(contactName);
request.setPhone(phone);
request.setBuilding(building);
request.setRoom(room);
request.setDefault(isDefault);
return request;
}
}