test
This commit is contained in:
5
.claude/settings.json
Normal file
5
.claude/settings.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"enabledPlugins": {
|
||||
"everything-claude-code@everything-claude-code": true
|
||||
}
|
||||
}
|
||||
271
.gitignore
vendored
271
.gitignore
vendored
@@ -1,23 +1,83 @@
|
||||
# Dependencies
|
||||
# ============================================
|
||||
# 爱维宠物医院管理系统 - Gitignore
|
||||
# Java Spring Boot + Vue.js 全栈项目
|
||||
# ============================================
|
||||
|
||||
# ============================================
|
||||
# 依赖目录
|
||||
# ============================================
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
bower_components/
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
# ============================================
|
||||
# 构建输出
|
||||
# ============================================
|
||||
# Frontend
|
||||
dist/
|
||||
frontend/dist/
|
||||
|
||||
# Backend
|
||||
target/
|
||||
backend/target/
|
||||
build/
|
||||
build/Release
|
||||
|
||||
# ============================================
|
||||
# 日志文件
|
||||
# ============================================
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
.lerna-debug.log*
|
||||
|
||||
# Production builds
|
||||
dist/
|
||||
build/
|
||||
target/
|
||||
# 项目特定的日志文件
|
||||
backend/*.log
|
||||
frontend/*.log
|
||||
backend_*.log
|
||||
frontend_*.log
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
# ============================================
|
||||
# IDE 和编辑器
|
||||
# ============================================
|
||||
# IntelliJ IDEA
|
||||
.idea/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
# VS Code
|
||||
.vscode/
|
||||
*.code-workspace
|
||||
|
||||
# Eclipse
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
# NetBeans
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
|
||||
# Vim/Emacs
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS generated files
|
||||
# ============================================
|
||||
# 操作系统文件
|
||||
# ============================================
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
@@ -26,107 +86,148 @@ target/
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
desktop.ini
|
||||
Icon?
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# Environment variables
|
||||
# ============================================
|
||||
# 环境变量和敏感配置
|
||||
# ============================================
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
.env.development
|
||||
.env.test
|
||||
.env.production
|
||||
|
||||
# Java/Maven
|
||||
# 应用配置(可能包含敏感信息)
|
||||
application-local.yml
|
||||
application-dev-local.yml
|
||||
application-prod.yml
|
||||
|
||||
# ============================================
|
||||
# Java / Maven / Spring Boot
|
||||
# ============================================
|
||||
*.class
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
*.tar.gz
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
*.zip
|
||||
|
||||
# Maven
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
.mvn/wrapper/maven-wrapper.properties
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.lerna-debug.log*
|
||||
# Gradle
|
||||
.gradle
|
||||
build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
gradle-app.setting
|
||||
.gradletasknamecache
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
# Spring Boot
|
||||
spring-boot-devtools.properties
|
||||
|
||||
# ============================================
|
||||
# Node.js / 前端
|
||||
# ============================================
|
||||
# Package locks (根据需要选择保留或忽略)
|
||||
# package-lock.json
|
||||
# yarn.lock
|
||||
# pnpm-lock.yaml
|
||||
|
||||
# TypeScript
|
||||
*.tsbuildinfo
|
||||
typings/
|
||||
|
||||
# Vue.js
|
||||
.vue-temp/
|
||||
|
||||
# Vite
|
||||
.vite/
|
||||
|
||||
# Sass/SCSS
|
||||
.sass-cache
|
||||
|
||||
# Coverage
|
||||
coverage/
|
||||
lib-cov/
|
||||
.nyc_output
|
||||
|
||||
# Database
|
||||
# ============================================
|
||||
# 数据库
|
||||
# ============================================
|
||||
*.sqlite
|
||||
*.sqlite-journal
|
||||
*.db
|
||||
*.db-journal
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
# ============================================
|
||||
# 运行时数据
|
||||
# ============================================
|
||||
pids/
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
# ============================================
|
||||
# 测试和临时文件
|
||||
# ============================================
|
||||
tmp/
|
||||
temp/
|
||||
*.tmp
|
||||
*.temp
|
||||
.cache/
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#files-in-tmp-and-tmp-grunt-tasks)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# TypeDoc docs
|
||||
docs/
|
||||
|
||||
# Sass
|
||||
.sass-cache
|
||||
|
||||
# Output of 'bundle gem {NAME}'
|
||||
*.gem
|
||||
*.rbc
|
||||
|
||||
# Configuration files
|
||||
config/
|
||||
*.ini
|
||||
*.toml
|
||||
|
||||
# Maven wrapper
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
# Backend build artifacts
|
||||
backend/target/
|
||||
backend/*.log
|
||||
|
||||
# Frontend build artifacts
|
||||
frontend/dist/
|
||||
frontend/node_modules/
|
||||
frontend/*.log
|
||||
|
||||
# FRP binaries (large files)
|
||||
# ============================================
|
||||
# FRP 内网穿透工具
|
||||
# ============================================
|
||||
frp/frpc
|
||||
frp/frps
|
||||
frp/*.ini
|
||||
frp/*.toml
|
||||
|
||||
# System files
|
||||
Thumbs.db
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
ehthumbs.db
|
||||
Icon?
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
# ============================================
|
||||
# 文档生成(保留源文件,忽略生成的)
|
||||
# ============================================
|
||||
# PlantUML 生成的图片
|
||||
*.png
|
||||
*.svg
|
||||
|
||||
# 但保留 docs/drawio 和 docs/plantuml 源文件
|
||||
!docs/**/*.drawio
|
||||
!docs/**/*.puml
|
||||
|
||||
# ============================================
|
||||
# 其他
|
||||
# ============================================
|
||||
# 备份文件
|
||||
*.bak
|
||||
*.backup
|
||||
*.orig
|
||||
|
||||
# 压缩文件
|
||||
*.7z
|
||||
*.rar
|
||||
|
||||
# 证书和密钥
|
||||
*.pem
|
||||
*.key
|
||||
*.crt
|
||||
*.p12
|
||||
*.pfx
|
||||
|
||||
# 上传文件目录(开发环境)
|
||||
uploads/
|
||||
files/
|
||||
|
||||
@@ -47,7 +47,7 @@ public class AppointmentController {
|
||||
return ApiResponse.success(appointmentService.page(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@GetMapping("/admin")
|
||||
public ApiResponse<?> adminList(@RequestParam(defaultValue = "1") long page,
|
||||
@RequestParam(defaultValue = "10") long size,
|
||||
@@ -59,7 +59,7 @@ public class AppointmentController {
|
||||
return ApiResponse.success(appointmentService.page(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PutMapping("/{id}/status")
|
||||
public ApiResponse<?> updateStatus(@PathVariable Long id, @RequestParam String status) {
|
||||
Appointment update = new Appointment();
|
||||
|
||||
@@ -17,7 +17,7 @@ public class DrugController {
|
||||
this.drugService = drugService;
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@GetMapping
|
||||
public ApiResponse<?> list(@RequestParam(defaultValue = "1") long page,
|
||||
@RequestParam(defaultValue = "10") long size,
|
||||
@@ -31,7 +31,7 @@ public class DrugController {
|
||||
return ApiResponse.success(drugService.page(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@PostMapping
|
||||
public ApiResponse<?> create(@RequestBody Drug drug) {
|
||||
if (drug.getStatus() == null) {
|
||||
@@ -41,7 +41,7 @@ public class DrugController {
|
||||
return ApiResponse.success("created", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@PutMapping("/{id}")
|
||||
public ApiResponse<?> update(@PathVariable Long id, @RequestBody Drug drug) {
|
||||
drug.setId(id);
|
||||
@@ -49,7 +49,7 @@ public class DrugController {
|
||||
return ApiResponse.success("updated", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@DeleteMapping("/{id}")
|
||||
public ApiResponse<?> delete(@PathVariable Long id) {
|
||||
drugService.removeById(id);
|
||||
|
||||
@@ -16,7 +16,7 @@ public class MedicalRecordController {
|
||||
this.medicalRecordService = medicalRecordService;
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PostMapping
|
||||
public ApiResponse<?> create(@RequestBody MedicalRecord record) {
|
||||
if (record.getStatus() == null) {
|
||||
@@ -33,7 +33,7 @@ public class MedicalRecordController {
|
||||
return ApiResponse.success(medicalRecordService.list(wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PutMapping("/{id}")
|
||||
public ApiResponse<?> update(@PathVariable Long id, @RequestBody MedicalRecord record) {
|
||||
record.setId(id);
|
||||
@@ -41,7 +41,7 @@ public class MedicalRecordController {
|
||||
return ApiResponse.success("updated", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@DeleteMapping("/{id}")
|
||||
public ApiResponse<?> delete(@PathVariable Long id) {
|
||||
medicalRecordService.removeById(id);
|
||||
|
||||
@@ -35,7 +35,7 @@ public class MessageController {
|
||||
return ApiResponse.success("created", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping("/admin")
|
||||
public ApiResponse<?> list(@RequestParam(defaultValue = "1") long page,
|
||||
@RequestParam(defaultValue = "10") long size,
|
||||
@@ -47,7 +47,7 @@ public class MessageController {
|
||||
return ApiResponse.success(messageService.page(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@PutMapping("/admin/{id}/reply")
|
||||
public ApiResponse<?> reply(@PathVariable Long id, @Valid @RequestBody ReplyRequest request) {
|
||||
AuthUser user = SecurityUtils.currentUser();
|
||||
|
||||
@@ -34,14 +34,14 @@ public class NoticeController {
|
||||
return ApiResponse.success(noticeService.getById(id));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping("/notices")
|
||||
public ApiResponse<?> list(@RequestParam(defaultValue = "1") long page,
|
||||
@RequestParam(defaultValue = "10") long size) {
|
||||
return ApiResponse.success(noticeService.page(new Page<>(page, size)));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@PostMapping("/notices")
|
||||
public ApiResponse<?> create(@RequestBody Notice notice) {
|
||||
if (notice.getPublisherId() == null) {
|
||||
@@ -60,7 +60,7 @@ public class NoticeController {
|
||||
return ApiResponse.success("created", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@PutMapping("/notices/{id}")
|
||||
public ApiResponse<?> update(@PathVariable Long id, @RequestBody Notice notice) {
|
||||
notice.setId(id);
|
||||
@@ -68,7 +68,7 @@ public class NoticeController {
|
||||
return ApiResponse.success("updated", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@DeleteMapping("/notices/{id}")
|
||||
public ApiResponse<?> delete(@PathVariable Long id) {
|
||||
noticeService.removeById(id);
|
||||
|
||||
@@ -44,7 +44,7 @@ public class OrderController {
|
||||
/**
|
||||
* 根据处方生成订单
|
||||
*/
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PostMapping("/from-prescription/{prescriptionId}")
|
||||
public ApiResponse<?> createFromPrescription(@PathVariable Long prescriptionId) {
|
||||
// 1. 查询处方
|
||||
@@ -164,7 +164,7 @@ public class OrderController {
|
||||
return ApiResponse.success(orderService.page(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PutMapping("/{id}")
|
||||
public ApiResponse<?> update(@PathVariable Long id, @RequestBody Order order) {
|
||||
order.setId(id);
|
||||
|
||||
@@ -72,7 +72,7 @@ public class PetController {
|
||||
return ApiResponse.success("deleted", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping("/admin/all")
|
||||
public ApiResponse<?> adminList(@RequestParam(defaultValue = "1") long page,
|
||||
@RequestParam(defaultValue = "10") long size) {
|
||||
|
||||
@@ -19,7 +19,7 @@ public class PrescriptionController {
|
||||
this.prescriptionService = prescriptionService;
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PostMapping
|
||||
public ApiResponse<?> create(@RequestBody Prescription prescription) {
|
||||
if (prescription.getStatus() == null) {
|
||||
@@ -44,7 +44,7 @@ public class PrescriptionController {
|
||||
return ApiResponse.success(prescriptionService.page(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PutMapping("/{id}")
|
||||
public ApiResponse<?> update(@PathVariable Long id, @RequestBody Prescription prescription) {
|
||||
prescription.setId(id);
|
||||
|
||||
@@ -23,14 +23,14 @@ public class PrescriptionItemController {
|
||||
return ApiResponse.success(prescriptionItemService.list(wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PostMapping
|
||||
public ApiResponse<?> create(@RequestBody PrescriptionItem item) {
|
||||
prescriptionItemService.save(item);
|
||||
return ApiResponse.success("created", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PutMapping("/{id}")
|
||||
public ApiResponse<?> update(@PathVariable Long id, @RequestBody PrescriptionItem item) {
|
||||
item.setId(id);
|
||||
@@ -38,7 +38,7 @@ public class PrescriptionItemController {
|
||||
return ApiResponse.success("updated", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@DeleteMapping("/{id}")
|
||||
public ApiResponse<?> delete(@PathVariable Long id) {
|
||||
prescriptionItemService.removeById(id);
|
||||
|
||||
@@ -19,7 +19,7 @@ public class ReportController {
|
||||
this.reportService = reportService;
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PostMapping
|
||||
public ApiResponse<?> create(@RequestBody Report report) {
|
||||
AuthUser user = SecurityUtils.currentUser();
|
||||
@@ -45,7 +45,7 @@ public class ReportController {
|
||||
return ApiResponse.success(reportService.page(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PutMapping("/{id}")
|
||||
public ApiResponse<?> update(@PathVariable Long id, @RequestBody Report report) {
|
||||
report.setId(id);
|
||||
@@ -53,7 +53,7 @@ public class ReportController {
|
||||
return ApiResponse.success("updated", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@DeleteMapping("/{id}")
|
||||
public ApiResponse<?> delete(@PathVariable Long id) {
|
||||
reportService.removeById(id);
|
||||
|
||||
@@ -6,12 +6,14 @@ import com.gpf.pethospital.common.ApiResponse;
|
||||
import com.gpf.pethospital.entity.Appointment;
|
||||
import com.gpf.pethospital.entity.Order;
|
||||
import com.gpf.pethospital.entity.Pet;
|
||||
import com.gpf.pethospital.entity.PrescriptionItem;
|
||||
import com.gpf.pethospital.entity.User;
|
||||
import com.gpf.pethospital.entity.Visit;
|
||||
import com.gpf.pethospital.service.AppointmentService;
|
||||
import com.gpf.pethospital.service.DrugService;
|
||||
import com.gpf.pethospital.service.OrderService;
|
||||
import com.gpf.pethospital.service.PetService;
|
||||
import com.gpf.pethospital.service.PrescriptionItemService;
|
||||
import com.gpf.pethospital.service.UserService;
|
||||
import com.gpf.pethospital.service.VisitService;
|
||||
// import org.springframework.security.access.prepost.PreAuthorize;
|
||||
@@ -26,8 +28,11 @@ import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -40,22 +45,25 @@ public class StatsController {
|
||||
private final PetService petService;
|
||||
private final UserService userService;
|
||||
private final DrugService drugService;
|
||||
private final PrescriptionItemService prescriptionItemService;
|
||||
|
||||
public StatsController(OrderService orderService,
|
||||
AppointmentService appointmentService,
|
||||
VisitService visitService,
|
||||
PetService petService,
|
||||
UserService userService,
|
||||
DrugService drugService) {
|
||||
DrugService drugService,
|
||||
PrescriptionItemService prescriptionItemService) {
|
||||
this.orderService = orderService;
|
||||
this.appointmentService = appointmentService;
|
||||
this.visitService = visitService;
|
||||
this.petService = petService;
|
||||
this.userService = userService;
|
||||
this.drugService = drugService;
|
||||
this.prescriptionItemService = prescriptionItemService;
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping
|
||||
public ApiResponse<?> summary() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
@@ -124,7 +132,7 @@ public class StatsController {
|
||||
return ApiResponse.success(data);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping("/trends")
|
||||
public ApiResponse<?> trends(@RequestParam(defaultValue = "week") String period) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
@@ -209,7 +217,252 @@ public class StatsController {
|
||||
return ApiResponse.success(data);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping("/report/revenue")
|
||||
public ApiResponse<?> revenueReport(@RequestParam(defaultValue = "month") String period,
|
||||
@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate) {
|
||||
DateRange range = resolveDateRange(period, startDate, endDate);
|
||||
List<Order> paidOrders = orderService.list(
|
||||
new LambdaQueryWrapper<Order>()
|
||||
.eq(Order::getStatus, "PAID")
|
||||
.ge(Order::getCreateTime, range.start())
|
||||
.lt(Order::getCreateTime, range.end())
|
||||
);
|
||||
|
||||
Map<LocalDate, BigDecimal> amountByDay = new HashMap<>();
|
||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
||||
for (Order order : paidOrders) {
|
||||
BigDecimal amount = order.getAmount() == null ? BigDecimal.ZERO : order.getAmount();
|
||||
totalAmount = totalAmount.add(amount);
|
||||
if (order.getCreateTime() != null) {
|
||||
amountByDay.merge(order.getCreateTime().toLocalDate(), amount, BigDecimal::add);
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<String, Object>> trend = amountByDay.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.map(entry -> {
|
||||
Map<String, Object> point = new HashMap<>();
|
||||
point.put("date", entry.getKey().toString());
|
||||
point.put("amount", entry.getValue());
|
||||
return point;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
DateRange previous = range.shiftBack();
|
||||
BigDecimal previousTotalAmount = sumPaidOrderAmount(previous.start(), previous.end());
|
||||
double growthRate = BigDecimal.ZERO.compareTo(previousTotalAmount) == 0
|
||||
? 0D
|
||||
: totalAmount.subtract(previousTotalAmount)
|
||||
.multiply(BigDecimal.valueOf(100))
|
||||
.divide(previousTotalAmount, 2, java.math.RoundingMode.HALF_UP)
|
||||
.doubleValue();
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("period", period);
|
||||
data.put("startDate", range.start().toLocalDate().toString());
|
||||
data.put("endDate", range.end().minusDays(1).toLocalDate().toString());
|
||||
data.put("totalAmount", totalAmount);
|
||||
data.put("orderCount", paidOrders.size());
|
||||
data.put("averageAmount", paidOrders.isEmpty()
|
||||
? BigDecimal.ZERO
|
||||
: totalAmount.divide(BigDecimal.valueOf(paidOrders.size()), 2, java.math.RoundingMode.HALF_UP));
|
||||
data.put("growthRate", growthRate);
|
||||
data.put("trend", trend);
|
||||
return ApiResponse.success(data);
|
||||
}
|
||||
|
||||
@GetMapping("/report/revenue-sources")
|
||||
public ApiResponse<?> revenueSources(@RequestParam(defaultValue = "month") String period,
|
||||
@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate) {
|
||||
DateRange range = resolveDateRange(period, startDate, endDate);
|
||||
QueryWrapper<Order> wrapper = new QueryWrapper<>();
|
||||
wrapper.select("payment_method AS paymentMethod", "COUNT(*) AS orderCount", "COALESCE(SUM(amount), 0) AS totalAmount");
|
||||
wrapper.eq("status", "PAID");
|
||||
wrapper.ge("create_time", range.start());
|
||||
wrapper.lt("create_time", range.end());
|
||||
wrapper.groupBy("payment_method");
|
||||
wrapper.orderByDesc("totalAmount");
|
||||
|
||||
List<Map<String, Object>> rows = orderService.listMaps(wrapper);
|
||||
BigDecimal totalAmount = rows.stream()
|
||||
.map(row -> toBigDecimal(getMapValue(row, "totalAmount", "totalamount", "TOTALAMOUNT")))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
List<Map<String, Object>> sources = new ArrayList<>();
|
||||
for (Map<String, Object> row : rows) {
|
||||
BigDecimal amount = toBigDecimal(getMapValue(row, "totalAmount", "totalamount", "TOTALAMOUNT"));
|
||||
Map<String, Object> item = new HashMap<>();
|
||||
item.put("paymentMethod", normalizePaymentMethod(String.valueOf(getMapValue(row, "paymentMethod", "payment_method", "PAYMENTMETHOD"))));
|
||||
item.put("orderCount", toLong(getMapValue(row, "orderCount", "ordercount", "ORDERCOUNT")));
|
||||
item.put("totalAmount", amount);
|
||||
item.put("ratio", BigDecimal.ZERO.compareTo(totalAmount) == 0
|
||||
? BigDecimal.ZERO
|
||||
: amount.multiply(BigDecimal.valueOf(100)).divide(totalAmount, 2, java.math.RoundingMode.HALF_UP));
|
||||
sources.add(item);
|
||||
}
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("period", period);
|
||||
data.put("startDate", range.start().toLocalDate().toString());
|
||||
data.put("endDate", range.end().minusDays(1).toLocalDate().toString());
|
||||
data.put("totalAmount", totalAmount);
|
||||
data.put("sources", sources);
|
||||
return ApiResponse.success(data);
|
||||
}
|
||||
|
||||
@GetMapping("/report/drug-sales")
|
||||
public ApiResponse<?> drugSales(@RequestParam(defaultValue = "month") String period,
|
||||
@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate,
|
||||
@RequestParam(defaultValue = "10") int limit) {
|
||||
DateRange range = resolveDateRange(period, startDate, endDate);
|
||||
QueryWrapper<PrescriptionItem> wrapper = new QueryWrapper<>();
|
||||
wrapper.select("drug_id AS drugId", "drug_name AS drugName", "COALESCE(SUM(quantity), 0) AS totalQuantity", "COALESCE(SUM(subtotal), 0) AS totalAmount");
|
||||
wrapper.ge("create_time", range.start());
|
||||
wrapper.lt("create_time", range.end());
|
||||
wrapper.groupBy("drug_id", "drug_name");
|
||||
wrapper.orderByDesc("totalQuantity");
|
||||
wrapper.orderByDesc("totalAmount");
|
||||
wrapper.last("LIMIT " + safeLimit(limit, 100));
|
||||
|
||||
List<Map<String, Object>> rows = prescriptionItemService.listMaps(wrapper);
|
||||
List<Map<String, Object>> ranking = new ArrayList<>();
|
||||
int rank = 1;
|
||||
for (Map<String, Object> row : rows) {
|
||||
Map<String, Object> item = new HashMap<>();
|
||||
item.put("rank", rank++);
|
||||
item.put("drugId", toLong(getMapValue(row, "drugId", "drug_id", "DRUGID")));
|
||||
item.put("drugName", normalizeDrugName(getMapValue(row, "drugName", "drug_name", "DRUGNAME")));
|
||||
item.put("totalQuantity", toLong(getMapValue(row, "totalQuantity", "totalquantity", "TOTALQUANTITY")));
|
||||
item.put("totalAmount", toBigDecimal(getMapValue(row, "totalAmount", "totalamount", "TOTALAMOUNT")));
|
||||
ranking.add(item);
|
||||
}
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("period", period);
|
||||
data.put("startDate", range.start().toLocalDate().toString());
|
||||
data.put("endDate", range.end().minusDays(1).toLocalDate().toString());
|
||||
data.put("ranking", ranking);
|
||||
return ApiResponse.success(data);
|
||||
}
|
||||
|
||||
@GetMapping("/report/doctor-performance")
|
||||
public ApiResponse<?> doctorPerformance(@RequestParam(defaultValue = "month") String period,
|
||||
@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate,
|
||||
@RequestParam(defaultValue = "10") int limit) {
|
||||
DateRange range = resolveDateRange(period, startDate, endDate);
|
||||
QueryWrapper<Visit> wrapper = new QueryWrapper<>();
|
||||
wrapper.select("doctor_id AS doctorId", "COUNT(*) AS visitCount", "COALESCE(SUM(total_amount), 0) AS totalAmount", "COALESCE(AVG(total_amount), 0) AS averageAmount");
|
||||
wrapper.ge("create_time", range.start());
|
||||
wrapper.lt("create_time", range.end());
|
||||
wrapper.isNotNull("doctor_id");
|
||||
wrapper.groupBy("doctor_id");
|
||||
wrapper.orderByDesc("totalAmount");
|
||||
wrapper.last("LIMIT " + safeLimit(limit, 100));
|
||||
|
||||
List<Map<String, Object>> rows = visitService.listMaps(wrapper);
|
||||
Set<Long> doctorIds = rows.stream()
|
||||
.map(row -> toLong(getMapValue(row, "doctorId", "doctor_id", "DOCTORID")))
|
||||
.filter(id -> id > 0)
|
||||
.collect(Collectors.toSet());
|
||||
Map<Long, String> doctorNameMap = userService.listByIds(doctorIds).stream()
|
||||
.collect(Collectors.toMap(User::getId, User::getUsername, (left, right) -> left));
|
||||
|
||||
List<Map<String, Object>> ranking = new ArrayList<>();
|
||||
int rank = 1;
|
||||
for (Map<String, Object> row : rows) {
|
||||
Long doctorId = toLong(getMapValue(row, "doctorId", "doctor_id", "DOCTORID"));
|
||||
Map<String, Object> item = new HashMap<>();
|
||||
item.put("rank", rank++);
|
||||
item.put("doctorId", doctorId);
|
||||
item.put("doctorName", doctorNameMap.getOrDefault(doctorId, "医生#" + doctorId));
|
||||
item.put("visitCount", toLong(getMapValue(row, "visitCount", "visitcount", "VISITCOUNT")));
|
||||
item.put("totalAmount", toBigDecimal(getMapValue(row, "totalAmount", "totalamount", "TOTALAMOUNT")));
|
||||
item.put("averageAmount", toBigDecimal(getMapValue(row, "averageAmount", "averageamount", "AVERAGEAMOUNT")));
|
||||
ranking.add(item);
|
||||
}
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("period", period);
|
||||
data.put("startDate", range.start().toLocalDate().toString());
|
||||
data.put("endDate", range.end().minusDays(1).toLocalDate().toString());
|
||||
data.put("ranking", ranking);
|
||||
return ApiResponse.success(data);
|
||||
}
|
||||
|
||||
@GetMapping("/report/department-performance")
|
||||
public ApiResponse<?> departmentPerformance(@RequestParam(defaultValue = "month") String period,
|
||||
@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate) {
|
||||
DateRange range = resolveDateRange(period, startDate, endDate);
|
||||
|
||||
QueryWrapper<Appointment> appointmentWrapper = new QueryWrapper<>();
|
||||
appointmentWrapper.select("department", "COUNT(*) AS appointmentCount");
|
||||
appointmentWrapper.ge("create_time", range.start());
|
||||
appointmentWrapper.lt("create_time", range.end());
|
||||
appointmentWrapper.groupBy("department");
|
||||
List<Map<String, Object>> appointmentRows = appointmentService.listMaps(appointmentWrapper);
|
||||
|
||||
Map<String, Long> appointmentCountMap = new HashMap<>();
|
||||
for (Map<String, Object> row : appointmentRows) {
|
||||
String department = normalizeDepartment(getMapValue(row, "department", "DEPARTMENT"));
|
||||
appointmentCountMap.put(department, toLong(getMapValue(row, "appointmentCount", "appointmentcount", "APPOINTMENTCOUNT")));
|
||||
}
|
||||
|
||||
List<Visit> visits = visitService.list(
|
||||
new LambdaQueryWrapper<Visit>()
|
||||
.ge(Visit::getCreateTime, range.start())
|
||||
.lt(Visit::getCreateTime, range.end())
|
||||
.isNotNull(Visit::getAppointmentId)
|
||||
);
|
||||
|
||||
Set<Long> appointmentIds = visits.stream()
|
||||
.map(Visit::getAppointmentId)
|
||||
.filter(id -> id != null && id > 0)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Map<Long, Appointment> appointmentMap = appointmentIds.isEmpty()
|
||||
? new HashMap<>()
|
||||
: appointmentService.listByIds(appointmentIds).stream()
|
||||
.collect(Collectors.toMap(Appointment::getId, appointment -> appointment, (left, right) -> left));
|
||||
|
||||
Map<String, Long> visitCountMap = new HashMap<>();
|
||||
Map<String, BigDecimal> revenueMap = new HashMap<>();
|
||||
for (Visit visit : visits) {
|
||||
Appointment appointment = appointmentMap.get(visit.getAppointmentId());
|
||||
String department = normalizeDepartment(appointment == null ? null : appointment.getDepartment());
|
||||
visitCountMap.merge(department, 1L, Long::sum);
|
||||
revenueMap.merge(department, visit.getTotalAmount() == null ? BigDecimal.ZERO : visit.getTotalAmount(), BigDecimal::add);
|
||||
}
|
||||
|
||||
Set<String> departments = new HashSet<>();
|
||||
departments.addAll(appointmentCountMap.keySet());
|
||||
departments.addAll(visitCountMap.keySet());
|
||||
|
||||
List<Map<String, Object>> departmentsData = departments.stream()
|
||||
.map(department -> {
|
||||
Map<String, Object> row = new HashMap<>();
|
||||
row.put("department", department);
|
||||
row.put("appointmentCount", appointmentCountMap.getOrDefault(department, 0L));
|
||||
row.put("visitCount", visitCountMap.getOrDefault(department, 0L));
|
||||
row.put("totalAmount", revenueMap.getOrDefault(department, BigDecimal.ZERO));
|
||||
return row;
|
||||
})
|
||||
.sorted((left, right) -> toBigDecimal(right.get("totalAmount")).compareTo(toBigDecimal(left.get("totalAmount"))))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("period", period);
|
||||
data.put("startDate", range.start().toLocalDate().toString());
|
||||
data.put("endDate", range.end().minusDays(1).toLocalDate().toString());
|
||||
data.put("departments", departmentsData);
|
||||
return ApiResponse.success(data);
|
||||
}
|
||||
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping("/today-todos")
|
||||
public ApiResponse<?> todayTodos() {
|
||||
LocalDate today = LocalDate.now();
|
||||
@@ -243,4 +496,139 @@ public class StatsController {
|
||||
|
||||
return ApiResponse.success(todoList);
|
||||
}
|
||||
|
||||
private DateRange resolveDateRange(String period, String startDate, String endDate) {
|
||||
if (hasText(startDate) && hasText(endDate)) {
|
||||
LocalDate start = LocalDate.parse(startDate);
|
||||
LocalDate end = LocalDate.parse(endDate);
|
||||
if (end.isBefore(start)) {
|
||||
LocalDate temp = start;
|
||||
start = end;
|
||||
end = temp;
|
||||
}
|
||||
return new DateRange(start.atStartOfDay(), end.plusDays(1).atStartOfDay());
|
||||
}
|
||||
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDate start;
|
||||
LocalDate end = today.plusDays(1);
|
||||
switch (period) {
|
||||
case "day":
|
||||
start = today;
|
||||
break;
|
||||
case "week":
|
||||
start = today.minusDays(6);
|
||||
break;
|
||||
case "year":
|
||||
start = today.minusMonths(11).withDayOfMonth(1);
|
||||
end = today.plusMonths(1).withDayOfMonth(1);
|
||||
break;
|
||||
case "month":
|
||||
default:
|
||||
start = today.minusDays(29);
|
||||
break;
|
||||
}
|
||||
return new DateRange(start.atStartOfDay(), end.atStartOfDay());
|
||||
}
|
||||
|
||||
private BigDecimal sumPaidOrderAmount(LocalDateTime start, LocalDateTime end) {
|
||||
QueryWrapper<Order> wrapper = new QueryWrapper<>();
|
||||
wrapper.select("COALESCE(SUM(amount), 0) AS totalAmount");
|
||||
wrapper.eq("status", "PAID");
|
||||
wrapper.ge("create_time", start);
|
||||
wrapper.lt("create_time", end);
|
||||
List<Map<String, Object>> rows = orderService.listMaps(wrapper);
|
||||
if (rows.isEmpty()) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return toBigDecimal(getMapValue(rows.get(0), "totalAmount", "totalamount", "TOTALAMOUNT"));
|
||||
}
|
||||
|
||||
private boolean hasText(String value) {
|
||||
return value != null && !value.isBlank();
|
||||
}
|
||||
|
||||
private int safeLimit(int value, int maxLimit) {
|
||||
if (value <= 0) {
|
||||
return 10;
|
||||
}
|
||||
return Math.min(value, maxLimit);
|
||||
}
|
||||
|
||||
private BigDecimal toBigDecimal(Object value) {
|
||||
if (value == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
if (value instanceof BigDecimal) {
|
||||
return (BigDecimal) value;
|
||||
}
|
||||
try {
|
||||
return new BigDecimal(value.toString());
|
||||
} catch (NumberFormatException ex) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
private long toLong(Object value) {
|
||||
if (value == null) {
|
||||
return 0L;
|
||||
}
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).longValue();
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(value.toString());
|
||||
} catch (NumberFormatException ex) {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
private Object getMapValue(Map<String, Object> row, String... keys) {
|
||||
for (String key : keys) {
|
||||
if (row.containsKey(key)) {
|
||||
return row.get(key);
|
||||
}
|
||||
}
|
||||
for (String key : keys) {
|
||||
for (Map.Entry<String, Object> entry : row.entrySet()) {
|
||||
if (entry.getKey().equalsIgnoreCase(key)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String normalizeDepartment(Object value) {
|
||||
String department = value == null ? "" : value.toString().trim();
|
||||
return department.isEmpty() ? "未分配科室" : department;
|
||||
}
|
||||
|
||||
private String normalizePaymentMethod(String value) {
|
||||
if (value == null || value.isBlank()) {
|
||||
return "未知支付方式";
|
||||
}
|
||||
switch (value) {
|
||||
case "ALIPAY":
|
||||
return "支付宝";
|
||||
case "WECHAT":
|
||||
return "微信支付";
|
||||
case "OFFLINE":
|
||||
return "线下支付";
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private String normalizeDrugName(Object value) {
|
||||
String name = value == null ? "" : value.toString().trim();
|
||||
return name.isEmpty() ? "未知药品" : name;
|
||||
}
|
||||
|
||||
private record DateRange(LocalDateTime start, LocalDateTime end) {
|
||||
private DateRange shiftBack() {
|
||||
long days = Math.max(1, ChronoUnit.DAYS.between(start.toLocalDate(), end.toLocalDate()));
|
||||
return new DateRange(start.minusDays(days), start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class StockInController {
|
||||
this.drugService = drugService;
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping
|
||||
public ApiResponse<?> list(@RequestParam(defaultValue = "1") long page,
|
||||
@RequestParam(defaultValue = "10") long size,
|
||||
@@ -34,7 +34,7 @@ public class StockInController {
|
||||
return ApiResponse.success(stockInService.page(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@PostMapping
|
||||
@Transactional
|
||||
public ApiResponse<?> create(@RequestBody StockIn stockIn) {
|
||||
|
||||
@@ -22,7 +22,7 @@ public class StockOutController {
|
||||
this.drugService = drugService;
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping
|
||||
public ApiResponse<?> list(@RequestParam(defaultValue = "1") long page,
|
||||
@RequestParam(defaultValue = "10") long size,
|
||||
@@ -34,7 +34,7 @@ public class StockOutController {
|
||||
return ApiResponse.success(stockOutService.page(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@PostMapping
|
||||
@Transactional
|
||||
public ApiResponse<?> create(@RequestBody StockOut stockOut) {
|
||||
|
||||
@@ -67,7 +67,7 @@ public class UserController {
|
||||
return ApiResponse.success(result);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@PostMapping
|
||||
public ApiResponse<?> create(@RequestBody User user) {
|
||||
if (user.getPassword() == null || user.getPassword().isBlank()) {
|
||||
@@ -81,7 +81,7 @@ public class UserController {
|
||||
return ApiResponse.success("created", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@PutMapping("/{id}/status")
|
||||
public ApiResponse<?> updateStatus(@PathVariable Long id, @RequestParam Integer status) {
|
||||
User update = new User();
|
||||
@@ -91,7 +91,7 @@ public class UserController {
|
||||
return ApiResponse.success("updated", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@PutMapping("/{id}/reset-password")
|
||||
public ApiResponse<?> resetPassword(@PathVariable Long id, @RequestParam String newPassword) {
|
||||
User update = new User();
|
||||
@@ -101,7 +101,7 @@ public class UserController {
|
||||
return ApiResponse.success("updated", null);
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasRole('ADMIN')")
|
||||
// @PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping("/stats")
|
||||
public ApiResponse<?> stats() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
|
||||
@@ -19,7 +19,7 @@ public class VisitController {
|
||||
this.visitService = visitService;
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PostMapping
|
||||
public ApiResponse<?> create(@RequestBody Visit visit) {
|
||||
if (visit.getStatus() == null) {
|
||||
@@ -47,7 +47,7 @@ public class VisitController {
|
||||
return ApiResponse.success(visitService.page(new Page<>(page, size), wrapper));
|
||||
}
|
||||
|
||||
@// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
// @PreAuthorize("hasAnyRole('ADMIN','DOCTOR')")
|
||||
@PutMapping("/{id}")
|
||||
public ApiResponse<?> update(@PathVariable Long id, @RequestBody Visit visit) {
|
||||
visit.setId(id);
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
@@ -52,6 +53,16 @@ public class Report {
|
||||
*/
|
||||
private Long doctorId;
|
||||
|
||||
private String reportType;
|
||||
|
||||
private String reportData;
|
||||
|
||||
private LocalDate periodStart;
|
||||
|
||||
private LocalDate periodEnd;
|
||||
|
||||
private Long generatedBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
server:
|
||||
port: 8081
|
||||
address: 0.0.0.0
|
||||
servlet:
|
||||
context-path: /api
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: pet-hospital
|
||||
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/pet_hospital_dev?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: qq5211314
|
||||
hikari:
|
||||
maximum-pool-size: 20
|
||||
minimum-idle: 10
|
||||
connection-timeout: 30000
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
show-sql: true
|
||||
|
||||
sql:
|
||||
init:
|
||||
mode: never
|
||||
schema-locations: classpath*:schema.sql
|
||||
data-locations: classpath*:data.sql
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: auto
|
||||
logic-delete-field: deleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
mapper-locations: classpath*:mapper/**/*.xml
|
||||
ddl-auto: create-drop
|
||||
|
||||
# JWT配置
|
||||
jwt:
|
||||
secret: petHospitalSecretKey2024GuanPengFeiGraduateDesign
|
||||
expiration: 86400000 # 24小时
|
||||
|
||||
# 文件上传配置
|
||||
file:
|
||||
upload-path: /tmp/pet-hospital/uploads/
|
||||
max-size: 10MB
|
||||
@@ -1,39 +0,0 @@
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
context-path: /api
|
||||
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
application:
|
||||
name: pet-hospital
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: auto
|
||||
logic-delete-field: deleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
mapper-locations: classpath*:mapper/**/*.xml
|
||||
|
||||
# 数据库配置
|
||||
database:
|
||||
type: mysql
|
||||
|
||||
# JWT配置
|
||||
jwt:
|
||||
secret: pet-hospital-secret-key-2024-guanpengfei-graduate-design
|
||||
expiration: 86400000 # 24小时
|
||||
|
||||
# 文件上传配置
|
||||
file:
|
||||
upload-path: /tmp/pet-hospital/uploads/
|
||||
max-size: 10MB
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user