完善统计功能并优化前端界面
后端: - 扩展 StatsController,新增趋势分析(/trends)和今日待办(/today-todos)接口 - 更新 application-dev.yml 数据库配置(端口3306,允许公钥检索) - 完善 pom.xml Maven 编译器插件和 Lombok 版本配置 - 添加 build-with-idea.sh 构建脚本 前端: - 新增 Register.vue 注册页面 - 优化 Dashboard 仪表盘布局和数据统计展示 - 改进 MainLayout 侧边栏样式和品牌展示 - 更新 Login 登录页面样式 - 新增 theme.css 主题样式文件 - 扩展 API 接口(statsTrends、todayTodos) - 更新路由和全局样式 文档: - 添加功能检查报告和功能列表文档
This commit is contained in:
270
backend/build-with-idea.sh
Executable file
270
backend/build-with-idea.sh
Executable file
@@ -0,0 +1,270 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 爱维宠物医院管理平台 - 打包启动一条龙脚本
|
||||
# 使用 IntelliJ IDEA 内置 JDK 和 Maven
|
||||
# 支持 IDEA 和 IDEA CE 版本
|
||||
|
||||
# 查找 IDEA 安装路径
|
||||
if [ -d "/Applications/IntelliJ IDEA.app" ]; then
|
||||
IDEA_HOME="/Applications/IntelliJ IDEA.app"
|
||||
elif [ -d "/Applications/IntelliJ IDEA CE.app" ]; then
|
||||
IDEA_HOME="/Applications/IntelliJ IDEA CE.app"
|
||||
else
|
||||
echo "❌ 错误: 未找到 IntelliJ IDEA 安装目录"
|
||||
echo "请确保 IDEA 安装在 /Applications 目录下"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 设置 IDEA 内置 JDK
|
||||
export JAVA_HOME="$IDEA_HOME/Contents/jbr/Contents/Home"
|
||||
export PATH="$JAVA_HOME/bin:$PATH"
|
||||
|
||||
# 设置 IDEA 内置 Maven
|
||||
MAVEN_BIN="$IDEA_HOME/Contents/plugins/maven/lib/maven3/bin/mvn"
|
||||
|
||||
if [ ! -f "$MAVEN_BIN" ]; then
|
||||
echo "❌ 错误: 未找到 IDEA 内置 Maven"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 脚本所在目录
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# 默认配置
|
||||
JAR_NAME="pet-hospital-1.0.0.jar"
|
||||
JAR_PATH="target/$JAR_NAME"
|
||||
SERVER_PORT="8080"
|
||||
ACTIVE_PROFILE="dev"
|
||||
SKIP_TESTS="-DskipTests"
|
||||
BACKGROUND=false
|
||||
DEBUG_MODE=false
|
||||
JVM_OPTS="-Xms512m -Xmx1g"
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 显示帮助信息
|
||||
show_help() {
|
||||
echo "爱维宠物医院管理平台 - 打包启动脚本"
|
||||
echo ""
|
||||
echo "用法: $0 [选项]"
|
||||
echo ""
|
||||
echo "选项:"
|
||||
echo " -p, --port PORT 指定服务端口号 (默认: 8080)"
|
||||
echo " -e, --env ENV 指定环境配置 (默认: dev, 可选: dev/prod)"
|
||||
echo " -t, --test 运行测试 (默认跳过测试)"
|
||||
echo " -b, --background 后台运行"
|
||||
echo " -d, --debug 开启调试模式 (端口: 5005)"
|
||||
echo " -c, --clean 仅清理,不打包"
|
||||
echo " -s, --stop 停止正在运行的服务"
|
||||
echo " -l, --logs 查看后台运行日志"
|
||||
echo " -h, --help 显示帮助信息"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 # 打包并启动"
|
||||
echo " $0 -p 8081 # 使用端口 8081 启动"
|
||||
echo " $0 -e prod # 使用生产环境配置"
|
||||
echo " $0 -b # 后台运行"
|
||||
echo " $0 -d # 调试模式"
|
||||
echo " $0 -s # 停止服务"
|
||||
echo " $0 -l # 查看日志"
|
||||
}
|
||||
|
||||
# 解析参数
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-p|--port)
|
||||
SERVER_PORT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-e|--env)
|
||||
ACTIVE_PROFILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-t|--test)
|
||||
SKIP_TESTS=""
|
||||
shift
|
||||
;;
|
||||
-b|--background)
|
||||
BACKGROUND=true
|
||||
shift
|
||||
;;
|
||||
-d|--debug)
|
||||
DEBUG_MODE=true
|
||||
shift
|
||||
;;
|
||||
-c|--clean)
|
||||
echo "🧹 清理项目..."
|
||||
"$MAVEN_BIN" clean
|
||||
echo "✅ 清理完成"
|
||||
exit 0
|
||||
;;
|
||||
-s|--stop)
|
||||
echo "🛑 停止服务..."
|
||||
PID=$(lsof -ti:$SERVER_PORT 2>/dev/null || echo "")
|
||||
if [ -n "$PID" ]; then
|
||||
kill $PID 2>/dev/null
|
||||
sleep 2
|
||||
if ps -p $PID > /dev/null 2>&1; then
|
||||
kill -9 $PID 2>/dev/null
|
||||
fi
|
||||
echo "✅ 服务已停止 (端口: $SERVER_PORT)"
|
||||
else
|
||||
# 尝试通过进程名查找
|
||||
PID=$(pgrep -f "$JAR_NAME" | head -1)
|
||||
if [ -n "$PID" ]; then
|
||||
kill $PID 2>/dev/null
|
||||
sleep 2
|
||||
if ps -p $PID > /dev/null 2>&1; then
|
||||
kill -9 $PID 2>/dev/null
|
||||
fi
|
||||
echo "✅ 服务已停止"
|
||||
else
|
||||
echo "⚠️ 未找到运行中的服务"
|
||||
fi
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
-l|--logs)
|
||||
if [ -f "$SCRIPT_DIR/app.log" ]; then
|
||||
echo "📋 查看日志 (按 Ctrl+C 退出)..."
|
||||
tail -f "$SCRIPT_DIR/app.log"
|
||||
else
|
||||
echo "❌ 未找到日志文件"
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "❌ 未知选项: $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 检查端口是否被占用
|
||||
check_port() {
|
||||
if lsof -Pi :$SERVER_PORT -sTCP:LISTEN -t >/dev/null 2>&1; then
|
||||
echo -e "${YELLOW}⚠️ 警告: 端口 $SERVER_PORT 已被占用${NC}"
|
||||
echo ""
|
||||
echo "占用端口的进程:"
|
||||
lsof -Pi :$SERVER_PORT -sTCP:LISTEN
|
||||
echo ""
|
||||
read -p "是否停止现有进程并继续? (y/n): " -n 1 -r
|
||||
echo ""
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
PID=$(lsof -ti:$SERVER_PORT)
|
||||
kill $PID 2>/dev/null
|
||||
sleep 2
|
||||
echo -e "${GREEN}✅ 已释放端口 $SERVER_PORT${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ 操作已取消${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# 显示环境信息
|
||||
show_info() {
|
||||
echo -e "${BLUE}═══════════════════════════════════════${NC}"
|
||||
echo -e "${BLUE} 爱维宠物医院管理平台 - 打包启动脚本${NC}"
|
||||
echo -e "${BLUE}═══════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}📦 使用 IDEA 内置 JDK:${NC} $JAVA_HOME"
|
||||
echo -e "${GREEN}🔧 Java 版本:${NC}"
|
||||
java -version 2>&1 | head -1
|
||||
echo ""
|
||||
echo -e "${GREEN}🚀 运行配置:${NC}"
|
||||
echo " 端口: $SERVER_PORT"
|
||||
echo " 环境: $ACTIVE_PROFILE"
|
||||
echo " 调试: $([ "$DEBUG_MODE" = true ] && echo "开启 (端口: 5005)" || echo "关闭")"
|
||||
echo " 后台: $([ "$BACKGROUND" = true ] && echo "是" || echo "否")"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 打包项目
|
||||
build_project() {
|
||||
echo -e "${BLUE}📦 开始打包项目...${NC}"
|
||||
echo ""
|
||||
|
||||
if ! "$MAVEN_BIN" clean package $SKIP_TESTS; then
|
||||
echo ""
|
||||
echo -e "${RED}❌ 打包失败!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ 打包成功!${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 启动应用
|
||||
start_app() {
|
||||
if [ ! -f "$JAR_PATH" ]; then
|
||||
echo -e "${RED}❌ 错误: 未找到 jar 文件: $JAR_PATH${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
check_port
|
||||
|
||||
# 构建启动命令
|
||||
JAVA_OPTS="$JVM_OPTS"
|
||||
|
||||
if [ "$DEBUG_MODE" = true ]; then
|
||||
JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
|
||||
echo -e "${YELLOW}🐛 调试模式已开启,可在 IDEA 中配置远程调试 (端口: 5005)${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}🚀 正在启动应用...${NC}"
|
||||
echo ""
|
||||
|
||||
if [ "$BACKGROUND" = true ]; then
|
||||
# 后台运行
|
||||
nohup java $JAVA_OPTS -jar "$JAR_PATH" \
|
||||
--server.port=$SERVER_PORT \
|
||||
--spring.profiles.active=$ACTIVE_PROFILE \
|
||||
> "$SCRIPT_DIR/app.log" 2>&1 &
|
||||
|
||||
APP_PID=$!
|
||||
echo $APP_PID > "$SCRIPT_DIR/app.pid"
|
||||
|
||||
echo -e "${GREEN}✅ 应用已在后台启动${NC}"
|
||||
echo " 进程ID: $APP_PID"
|
||||
echo " 访问地址: http://localhost:$SERVER_PORT"
|
||||
echo " 日志文件: $SCRIPT_DIR/app.log"
|
||||
echo ""
|
||||
echo "查看日志: $0 --logs"
|
||||
echo "停止服务: $0 --stop"
|
||||
else
|
||||
# 前台运行
|
||||
echo -e "${GREEN}✅ 应用启动成功!${NC}"
|
||||
echo " 访问地址: http://localhost:$SERVER_PORT"
|
||||
echo " API 文档: http://localhost:$SERVER_PORT/swagger-ui.html"
|
||||
echo ""
|
||||
echo -e "${YELLOW}按 Ctrl+C 停止服务${NC}"
|
||||
echo "═══════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
java $JAVA_OPTS -jar "$JAR_PATH" \
|
||||
--server.port=$SERVER_PORT \
|
||||
--spring.profiles.active=$ACTIVE_PROFILE
|
||||
fi
|
||||
}
|
||||
|
||||
# 主流程
|
||||
main() {
|
||||
show_info
|
||||
build_project
|
||||
start_app
|
||||
}
|
||||
|
||||
main
|
||||
@@ -88,6 +88,7 @@
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.34</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@@ -108,6 +109,23 @@
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
<release>17</release>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.36</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
|
||||
@@ -3,9 +3,13 @@ package com.gpf.pethospital.controller;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
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.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.UserService;
|
||||
@@ -13,12 +17,19 @@ import com.gpf.pethospital.service.VisitService;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/stats")
|
||||
@@ -28,40 +39,208 @@ public class StatsController {
|
||||
private final VisitService visitService;
|
||||
private final PetService petService;
|
||||
private final UserService userService;
|
||||
private final DrugService drugService;
|
||||
|
||||
public StatsController(OrderService orderService,
|
||||
AppointmentService appointmentService,
|
||||
VisitService visitService,
|
||||
PetService petService,
|
||||
UserService userService) {
|
||||
UserService userService,
|
||||
DrugService drugService) {
|
||||
this.orderService = orderService;
|
||||
this.appointmentService = appointmentService;
|
||||
this.visitService = visitService;
|
||||
this.petService = petService;
|
||||
this.userService = userService;
|
||||
this.drugService = drugService;
|
||||
}
|
||||
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping
|
||||
public ApiResponse<?> summary() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("orders", orderService.count());
|
||||
data.put("appointments", appointmentService.count());
|
||||
data.put("visits", visitService.count());
|
||||
data.put("pets", petService.count());
|
||||
data.put("customers", userService.count(new LambdaQueryWrapper<User>().eq(User::getRole, "CUSTOMER")));
|
||||
|
||||
QueryWrapper<Order> wrapper = new QueryWrapper<>();
|
||||
wrapper.select("SUM(amount) AS total");
|
||||
List<Map<String, Object>> result = orderService.listMaps(wrapper);
|
||||
BigDecimal total = BigDecimal.ZERO;
|
||||
|
||||
// 今日预约数
|
||||
LocalDate today = LocalDate.now();
|
||||
long todayAppointments = appointmentService.count(
|
||||
new LambdaQueryWrapper<Appointment>()
|
||||
.eq(Appointment::getAppointmentDate, today)
|
||||
.ne(Appointment::getStatus, "CANCELLED")
|
||||
);
|
||||
data.put("appointments", todayAppointments);
|
||||
|
||||
// 今日待就诊数(预约状态为 CONFIRMED 的今日预约)
|
||||
long pendingVisits = appointmentService.count(
|
||||
new LambdaQueryWrapper<Appointment>()
|
||||
.eq(Appointment::getAppointmentDate, today)
|
||||
.eq(Appointment::getStatus, "CONFIRMED")
|
||||
);
|
||||
data.put("visits", pendingVisits);
|
||||
|
||||
// 药品库存总数
|
||||
QueryWrapper<com.gpf.pethospital.entity.Drug> drugWrapper = new QueryWrapper<>();
|
||||
drugWrapper.select("SUM(stock) AS totalStock");
|
||||
List<Map<String, Object>> drugResult = drugService.listMaps(drugWrapper);
|
||||
Long drugStock = 0L;
|
||||
if (!drugResult.isEmpty() && drugResult.get(0) != null && drugResult.get(0).get("totalStock") != null) {
|
||||
drugStock = Long.valueOf(drugResult.get(0).get("totalStock").toString());
|
||||
}
|
||||
data.put("drugs", drugStock);
|
||||
|
||||
// 今日收入
|
||||
LocalDateTime todayStart = today.atStartOfDay();
|
||||
LocalDateTime todayEnd = today.plusDays(1).atStartOfDay();
|
||||
QueryWrapper<Order> orderWrapper = new QueryWrapper<>();
|
||||
orderWrapper.select("SUM(amount) AS total");
|
||||
orderWrapper.ge("create_time", todayStart);
|
||||
orderWrapper.lt("create_time", todayEnd);
|
||||
List<Map<String, Object>> result = orderService.listMaps(orderWrapper);
|
||||
BigDecimal todayRevenue = BigDecimal.ZERO;
|
||||
if (!result.isEmpty()) {
|
||||
Map<String, Object> row = result.get(0);
|
||||
if (row != null && row.get("total") != null) {
|
||||
todayRevenue = new BigDecimal(row.get("total").toString());
|
||||
}
|
||||
}
|
||||
data.put("revenue", todayRevenue);
|
||||
|
||||
// 保留原有统计数据
|
||||
data.put("orders", orderService.count());
|
||||
data.put("pets", petService.count());
|
||||
data.put("customers", userService.count(new LambdaQueryWrapper<User>().eq(User::getRole, "CUSTOMER")));
|
||||
|
||||
QueryWrapper<Order> totalWrapper = new QueryWrapper<>();
|
||||
totalWrapper.select("SUM(amount) AS total");
|
||||
List<Map<String, Object>> totalResult = orderService.listMaps(totalWrapper);
|
||||
BigDecimal total = BigDecimal.ZERO;
|
||||
if (!totalResult.isEmpty()) {
|
||||
Map<String, Object> row = totalResult.get(0);
|
||||
if (row != null && row.get("total") != null) {
|
||||
total = new BigDecimal(row.get("total").toString());
|
||||
}
|
||||
}
|
||||
data.put("orderAmountTotal", total);
|
||||
|
||||
return ApiResponse.success(data);
|
||||
}
|
||||
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping("/trends")
|
||||
public ApiResponse<?> trends(@RequestParam(defaultValue = "week") String period) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
LocalDate now = LocalDate.now();
|
||||
LocalDate startDate;
|
||||
DateTimeFormatter formatter;
|
||||
int days;
|
||||
|
||||
switch (period) {
|
||||
case "month":
|
||||
startDate = now.minusDays(30);
|
||||
formatter = DateTimeFormatter.ofPattern("MM-dd");
|
||||
days = 30;
|
||||
break;
|
||||
case "year":
|
||||
startDate = now.minusMonths(12);
|
||||
formatter = DateTimeFormatter.ofPattern("yyyy-MM");
|
||||
days = 12;
|
||||
break;
|
||||
default: // week
|
||||
startDate = now.minusDays(6);
|
||||
formatter = DateTimeFormatter.ofPattern("MM-dd");
|
||||
days = 7;
|
||||
break;
|
||||
}
|
||||
|
||||
List<String> labels = new ArrayList<>();
|
||||
List<Integer> values = new ArrayList<>();
|
||||
|
||||
if ("year".equals(period)) {
|
||||
// 按月统计
|
||||
for (int i = 0; i < 12; i++) {
|
||||
LocalDate monthStart = startDate.plusMonths(i);
|
||||
LocalDateTime monthStartTime = monthStart.atStartOfDay();
|
||||
LocalDateTime monthEndTime = monthStart.plusMonths(1).atStartOfDay();
|
||||
|
||||
long count = visitService.count(
|
||||
new LambdaQueryWrapper<Visit>()
|
||||
.ge(Visit::getCreateTime, monthStartTime)
|
||||
.lt(Visit::getCreateTime, monthEndTime)
|
||||
);
|
||||
|
||||
labels.add(monthStart.format(formatter));
|
||||
values.add((int) count);
|
||||
}
|
||||
} else {
|
||||
// 按天统计
|
||||
for (int i = 0; i < days; i++) {
|
||||
LocalDate date = startDate.plusDays(i);
|
||||
LocalDateTime dayStart = date.atStartOfDay();
|
||||
LocalDateTime dayEnd = date.plusDays(1).atStartOfDay();
|
||||
|
||||
long count = visitService.count(
|
||||
new LambdaQueryWrapper<Visit>()
|
||||
.ge(Visit::getCreateTime, dayStart)
|
||||
.lt(Visit::getCreateTime, dayEnd)
|
||||
);
|
||||
|
||||
labels.add(date.format(formatter));
|
||||
values.add((int) count);
|
||||
}
|
||||
}
|
||||
|
||||
data.put("labels", labels);
|
||||
data.put("values", values);
|
||||
data.put("total", values.stream().mapToInt(Integer::intValue).sum());
|
||||
|
||||
// 计算环比
|
||||
if (values.size() >= 2) {
|
||||
int current = values.get(values.size() - 1);
|
||||
int previous = values.get(values.size() - 2);
|
||||
double growthRate = previous > 0 ? ((double) (current - previous) / previous * 100) : 0;
|
||||
data.put("growthRate", Math.round(growthRate * 10) / 10.0);
|
||||
} else {
|
||||
data.put("growthRate", 0);
|
||||
}
|
||||
|
||||
// 平均日接诊
|
||||
double avg = values.isEmpty() ? 0 : values.stream().mapToInt(Integer::intValue).average().orElse(0);
|
||||
data.put("average", Math.round(avg * 10) / 10.0);
|
||||
|
||||
return ApiResponse.success(data);
|
||||
}
|
||||
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
@GetMapping("/today-todos")
|
||||
public ApiResponse<?> todayTodos() {
|
||||
LocalDate today = LocalDate.now();
|
||||
|
||||
// 查询今日待就诊的预约
|
||||
List<Appointment> appointments = appointmentService.list(
|
||||
new LambdaQueryWrapper<Appointment>()
|
||||
.eq(Appointment::getAppointmentDate, today)
|
||||
.eq(Appointment::getStatus, "CONFIRMED")
|
||||
.orderByAsc(Appointment::getTimeSlot)
|
||||
);
|
||||
|
||||
List<Map<String, Object>> todoList = appointments.stream().map(appointment -> {
|
||||
Map<String, Object> todo = new HashMap<>();
|
||||
|
||||
// 获取客户信息
|
||||
User customer = userService.getById(appointment.getCustomerId());
|
||||
// 获取宠物信息
|
||||
Pet pet = petService.getById(appointment.getPetId());
|
||||
|
||||
todo.put("id", appointment.getId());
|
||||
todo.put("time", appointment.getTimeSlot());
|
||||
todo.put("customer", customer != null ? customer.getUsername() : "未知客户");
|
||||
todo.put("pet", pet != null ? pet.getName() + "(" + pet.getBreed() + ")" : "未知宠物");
|
||||
todo.put("service", appointment.getDepartment() != null ? appointment.getDepartment() : "常规就诊");
|
||||
todo.put("status", "待就诊");
|
||||
todo.put("action", "接诊");
|
||||
|
||||
return todo;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
return ApiResponse.success(todoList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
server:
|
||||
port: 8081
|
||||
address: 0.0.0.0
|
||||
servlet:
|
||||
context-path: /api
|
||||
|
||||
@@ -9,7 +10,7 @@ spring:
|
||||
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3307/pet_hospital_dev?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
|
||||
url: jdbc:mysql://localhost:3306/pet_hospital_dev?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: qq5211314
|
||||
hikari:
|
||||
|
||||
Reference in New Issue
Block a user