feat: add community content and address APIs
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
83
backend/src/main/java/com/linhelp/notice/BannerRequest.java
Normal file
83
backend/src/main/java/com/linhelp/notice/BannerRequest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
85
backend/src/main/java/com/linhelp/notice/BannerResponse.java
Normal file
85
backend/src/main/java/com/linhelp/notice/BannerResponse.java
Normal 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;
|
||||
}
|
||||
}
|
||||
81
backend/src/main/java/com/linhelp/notice/BannerService.java
Normal file
81
backend/src/main/java/com/linhelp/notice/BannerService.java
Normal 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());
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
67
backend/src/main/java/com/linhelp/notice/NoticeRequest.java
Normal file
67
backend/src/main/java/com/linhelp/notice/NoticeRequest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
87
backend/src/main/java/com/linhelp/notice/NoticeResponse.java
Normal file
87
backend/src/main/java/com/linhelp/notice/NoticeResponse.java
Normal 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;
|
||||
}
|
||||
}
|
||||
122
backend/src/main/java/com/linhelp/notice/NoticeService.java
Normal file
122
backend/src/main/java/com/linhelp/notice/NoticeService.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
98
backend/src/main/java/com/linhelp/user/AddressRequest.java
Normal file
98
backend/src/main/java/com/linhelp/user/AddressRequest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
94
backend/src/main/java/com/linhelp/user/AddressResponse.java
Normal file
94
backend/src/main/java/com/linhelp/user/AddressResponse.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user