From cc6577b3dfff9ed68eb728dc90091f0c36e6ced5 Mon Sep 17 00:00:00 2001 From: zhangjf Date: Mon, 2 Mar 2026 22:46:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E5=90=AF=E5=8A=A8=E8=84=9A=E6=9C=AC=E5=8F=8A?= =?UTF-8?q?=E5=90=84=E6=A8=A1=E5=9D=97=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 scripts/dev-start.sh: 本地开发环境启动脚本,支持启动所有/核心/单个服务 - 新增 scripts/dev-stop.sh: 本地开发环境停止脚本 - 新增 scripts/dev-status.sh: 服务状态检查脚本 - 优化各模块 Controller/Service/VO/DTO 代码 - 删除过时的计划文件 --- ...资金平台功能完善与架构增强计划_4e6331df.md | 298 ---------------- .../exp/controller/ExpenseTypeController.java | 12 +- .../exp/controller/FundExpenseController.java | 28 +- .../fundplatform/exp/dto/FundExpenseDTO.java | 32 +- .../exp/service/FundExpenseService.java | 22 +- .../service/impl/FundExpenseServiceImpl.java | 51 +-- .../fundplatform/exp/vo/FundExpenseVO.java | 56 ++- .../file/controller/FileController.java | 20 +- .../file/data/service/FileRecordService.java | 12 +- .../fundplatform/file/vo/FileRecordVO.java | 24 +- .../controller/RequirementController.java | 6 +- .../fundplatform/proj/dto/RequirementDTO.java | 22 +- .../proj/service/RequirementService.java | 6 +- .../receipt/service/FundReceiptService.java | 12 +- .../receipt/service/ReceivableService.java | 18 +- .../service/impl/FundReceiptServiceImpl.java | 12 +- .../service/impl/ReceivableServiceImpl.java | 18 +- .../fundplatform/receipt/vo/ReceivableVO.java | 42 +-- .../report/controller/ReportController.java | 8 +- .../report/dto/ProjectFinanceDTO.java | 6 +- .../report/feign/ProjectFeignClient.java | 4 +- .../report/service/ReportService.java | 2 +- .../service/impl/ReportServiceImpl.java | 12 +- .../controller/OperationLogController.java | 2 +- .../sys/data/entity/SysTenant.java | 4 +- .../sys/service/OperationLogService.java | 2 +- .../service/impl/OperationLogServiceImpl.java | 2 +- scripts/dev-start.sh | 323 ++++++++++++++++++ scripts/dev-status.sh | 138 ++++++++ scripts/dev-stop.sh | 237 +++++++++++++ 30 files changed, 914 insertions(+), 517 deletions(-) delete mode 100644 .qoder/plans/资金平台功能完善与架构增强计划_4e6331df.md create mode 100755 scripts/dev-start.sh create mode 100755 scripts/dev-status.sh create mode 100755 scripts/dev-stop.sh diff --git a/.qoder/plans/资金平台功能完善与架构增强计划_4e6331df.md b/.qoder/plans/资金平台功能完善与架构增强计划_4e6331df.md deleted file mode 100644 index f008575..0000000 --- a/.qoder/plans/资金平台功能完善与架构增强计划_4e6331df.md +++ /dev/null @@ -1,298 +0,0 @@ -# 资金平台功能完善与架构增强计划 - -## 前置条件 -- ✅ 六步实施已完成 -- ✅ 11个模块编译通过 -- ✅ 数据库初始化完成 -- ✅ fund-sys服务运行正常 -- ✅ Gateway路由配置完成 - ---- - -## A. 完善fund-sys权限管理 - -### A.1 用户管理模块 -**目标**: 实现用户CRUD接口 - -**实施步骤**: -1. 创建 `UserDTO.java` (用户创建/更新DTO) -2. 创建 `UserVO.java` (用户返回VO) -3. 创建 `UserService.java` 和 `UserServiceImpl.java` -4. 创建 `UserController.java` (REST接口) -5. 实现接口: - - `POST /api/v1/sys/user` - 创建用户 - - `PUT /api/v1/sys/user/{id}` - 更新用户 - - `GET /api/v1/sys/user/{id}` - 查询用户 - - `GET /api/v1/sys/user/page` - 分页查询 - - `DELETE /api/v1/sys/user/{id}` - 删除用户 - -**涉及文件**: -- `fund-sys/src/main/java/com/fundplatform/sys/dto/UserDTO.java` -- `fund-sys/src/main/java/com/fundplatform/sys/vo/UserVO.java` -- `fund-sys/src/main/java/com/fundplatform/sys/service/UserService.java` -- `fund-sys/src/main/java/com/fundplatform/sys/service/impl/UserServiceImpl.java` -- `fund-sys/src/main/java/com/fundplatform/sys/controller/UserController.java` - -### A.2 角色管理模块 -**实施步骤**: 同用户管理,创建Role相关类 -**接口**: `/api/v1/sys/role` 系列接口 - -### A.3 菜单管理模块 -**实施步骤**: 同用户管理,创建Menu相关类 -**接口**: `/api/v1/sys/menu` 系列接口 - -### A.4 部门管理模块 -**实施步骤**: 同用户管理,创建Dept相关类 -**接口**: `/api/v1/sys/dept` 系列接口 - -**验证**: 每个模块完成后执行 `mvn -pl fund-sys clean install` - ---- - -## B. 完善其他业务模块 - -### B.1 fund-req用款申请模块 -**目标**: 实现用款申请完整业务流程 - -**实施步骤**: -1. 创建 `FundRequest.java` 实体类 -2. 创建 `FundRequestMapper.java` 和 `FundRequestDataService.java` -3. 创建 `FundRequestService.java` 和实现类 -4. 创建 `FundRequestController.java` -5. 实现接口: - - `POST /api/v1/req/fund-request` - 创建申请 - - `PUT /api/v1/req/fund-request/{id}/approve` - 审批通过 - - `PUT /api/v1/req/fund-request/{id}/reject` - 审批拒绝 - - `GET /api/v1/req/fund-request/page` - 分页查询 - -**涉及文件**: -- `fund-req/src/main/java/com/fundplatform/req/data/entity/FundRequest.java` -- `fund-req/src/main/java/com/fundplatform/req/data/mapper/FundRequestMapper.java` -- `fund-req/src/main/java/com/fundplatform/req/data/service/FundRequestDataService.java` -- `fund-req/src/main/java/com/fundplatform/req/service/FundRequestService.java` -- `fund-req/src/main/java/com/fundplatform/req/controller/FundRequestController.java` - -### B.2 fund-exp支出管理模块 -**实施步骤**: 类似fund-req,创建支出相关类 - -### B.3 fund-receipt收款管理模块 -**实施步骤**: 类似fund-req,创建收款相关类 - ---- - -## C. Gateway增强 - -### C.1 全局日志过滤器 -**目标**: 记录所有请求日志,生成TraceId - -**实施步骤**: -1. 创建 `GlobalLogFilter.java` (实现GatewayFilter) -2. 生成TraceId并写入请求头 -3. 记录请求路径、方法、耗时 -4. 配置到application.yml - -**涉及文件**: -- `fund-gateway/src/main/java/com/fundplatform/gateway/filter/GlobalLogFilter.java` -- `fund-gateway/src/main/resources/application.yml` - -### C.2 JWT鉴权过滤器 -**目标**: 验证JWT Token,提取用户信息 - -**实施步骤**: -1. 创建 `JwtAuthFilter.java` -2. 验证Token有效性 -3. 提取userId、tenantId写入请求头 -4. 配置白名单路径(登录、健康检查等) - -**涉及文件**: -- `fund-gateway/src/main/java/com/fundplatform/gateway/filter/JwtAuthFilter.java` -- `fund-gateway/src/main/resources/application.yml` - -### C.3 限流配置 -**实施步骤**: -1. 添加Redis依赖 -2. 配置RequestRateLimiter过滤器 -3. 设置限流规则(每秒请求数) - ---- - -## D. 服务治理 - -### D.1 集成Nacos服务注册发现 -**目标**: 实现服务自动注册和发现 - -**实施步骤**: -1. 添加Nacos依赖到所有服务 -2. 配置Nacos地址(从memory获取: localhost:8848) -3. 配置服务名称和分组 -4. 启动服务验证注册成功 - -**涉及文件**: -- 所有服务的 `pom.xml` 添加nacos依赖 -- 所有服务的 `application.yml` 添加nacos配置 - -### D.2 集成Sentinel熔断降级 -**实施步骤**: -1. 添加Sentinel依赖 -2. 配置熔断规则 -3. 配置降级逻辑 - -### D.3 统一配置中心 -**实施步骤**: -1. 在Nacos创建配置文件 -2. 各服务从Nacos读取配置 - ---- - -## E. 日志与监控 - -### E.1 集成ELK日志聚合 -**目标**: 统一日志收集和分析 - -**实施步骤**: -1. 配置Logback输出JSON格式日志 -2. 部署Filebeat收集日志 -3. 部署Logstash处理日志 -4. 部署Elasticsearch存储日志 -5. 部署Kibana可视化 - -### E.2 集成SkyWalking链路追踪 -**实施步骤**: -1. 添加SkyWalking Agent -2. 配置链路追踪 -3. 集成Gateway和Feign - -### E.3 Prometheus+Grafana监控 -**实施步骤**: -1. 添加Micrometer依赖 -2. 配置Prometheus端点 -3. 部署Prometheus采集指标 -4. 部署Grafana可视化 - ---- - -## F. 数据库优化 - -### F.1 读写分离配置 -**实施步骤**: -1. 配置主从数据库 -2. 使用ShardingSphere实现读写分离 -3. 配置路由规则 - -### F.2 连接池优化 -**实施步骤**: -1. 优化HikariCP配置(连接数、超时时间) -2. 配置连接池监控 - -### F.3 索引优化 -**实施步骤**: -1. 分析慢查询SQL -2. 添加必要索引 -3. 优化查询语句 - ---- - -## G. 高可用架构 - -### G.1 服务集群部署 -**实施步骤**: -1. 各服务打包为Docker镜像 -2. 配置Docker Compose或K8s部署 -3. 配置负载均衡 - -### G.2 网关集群部署 -**实施步骤**: -1. Gateway多实例部署 -2. 配置Nginx负载均衡 - -### G.3 数据库高可用 -**实施步骤**: -1. 配置MySQL主从复制 -2. 配置自动故障切换 - ---- - -## H. 安全增强 - -### H.1 HTTPS配置 -**实施步骤**: -1. 生成SSL证书 -2. 配置Spring Boot HTTPS -3. 配置Gateway HTTPS - -### H.2 API签名验证 -**实施步骤**: -1. 设计签名算法(时间戳+密钥+签名) -2. 创建签名拦截器 -3. 各服务集成签名验证 - -### H.3 数据加密存储 -**实施步骤**: -1. 敏感字段加密(手机号、身份证等) -2. 使用AES或RSA加密 -3. 配置加解密工具类 - ---- - -## I. 性能优化 - -### I.1 Redis缓存集成 -**目标**: 减少数据库查询压力 - -**实施步骤**: -1. 添加Redis依赖(从memory获取密码: zjf@123456) -2. 配置Redis连接 -3. 实现缓存工具类 -4. 对热点数据添加缓存 - -**涉及文件**: -- `fund-common/src/main/java/com/fundplatform/common/cache/RedisService.java` -- 所有服务的 `pom.xml` 添加redis依赖 -- 所有服务的 `application.yml` 添加redis配置 - -### I.2 接口性能测试 -**实施步骤**: -1. 使用JMeter编写测试脚本 -2. 压测核心接口 -3. 分析性能瓶颈 -4. 优化慢接口 - -### I.3 异步处理优化 -**实施步骤**: -1. 引入消息队列(RabbitMQ/Kafka) -2. 异步处理耗时操作 -3. 实现最终一致性 - ---- - -## 实施优先级 - -| 优先级 | 模块 | 预计时间 | 依赖 | -|--------|------|----------|------| -| P0 | C.1 Gateway日志过滤器 | 2小时 | 无 | -| P0 | C.2 Gateway鉴权过滤器 | 3小时 | 无 | -| P1 | A.1 用户管理模块 | 4小时 | 无 | -| P1 | B.1 fund-req用款申请 | 4小时 | 无 | -| P1 | D.1 Nacos服务注册 | 4小时 | 无 | -| P2 | I.1 Redis缓存集成 | 4小时 | 无 | -| P2 | E.1 ELK日志聚合 | 1天 | 无 | -| P3 | 其他模块 | 按需 | 前置模块 | - ---- - -## 验证标准 - -每个阶段完成后需验证: -1. ✅ 编译通过: `mvn clean install` -2. ✅ 服务启动正常 -3. ✅ 接口测试通过 -4. ✅ Git提交代码 - ---- - -## 风险提示 - -1. **Spring Cloud版本兼容性**: 注意Spring Boot 3.2与Spring Cloud版本匹配 -2. **数据库性能**: 注意索引优化,避免慢查询 -3. **服务稳定性**: 添加熔断降级,防止雪崩 -4. **安全性**: API接口必须鉴权,敏感数据加密 \ No newline at end of file diff --git a/fund-exp/src/main/java/com/fundplatform/exp/controller/ExpenseTypeController.java b/fund-exp/src/main/java/com/fundplatform/exp/controller/ExpenseTypeController.java index 7bc94dd..9267ffd 100644 --- a/fund-exp/src/main/java/com/fundplatform/exp/controller/ExpenseTypeController.java +++ b/fund-exp/src/main/java/com/fundplatform/exp/controller/ExpenseTypeController.java @@ -28,7 +28,7 @@ public class ExpenseTypeController { * 创建支出类型 */ @PostMapping - public Result create(@Valid @RequestBody ExpenseTypeDTO dto) { + public Result create(@Valid @RequestBody ExpenseTypeDTO dto) { return Result.success(typeService.createType(dto)); } @@ -36,7 +36,7 @@ public class ExpenseTypeController { * 更新支出类型 */ @PutMapping("/{id}") - public Result update(@PathVariable Long id, @Valid @RequestBody ExpenseTypeDTO dto) { + public Result update(@PathVariable String id, @Valid @RequestBody ExpenseTypeDTO dto) { dto.setId(id); return Result.success(typeService.updateType(dto)); } @@ -72,7 +72,7 @@ public class ExpenseTypeController { * 根据ID查询支出类型 */ @GetMapping("/{id}") - public Result getById(@PathVariable Long id) { + public Result getById(@PathVariable String id) { return Result.success(typeService.getTypeById(id)); } @@ -80,7 +80,7 @@ public class ExpenseTypeController { * 查询指定父级的子类型列表 */ @GetMapping("/children") - public Result> getChildren(@RequestParam(required = false) Long parentId) { + public Result> getChildren(@RequestParam(required = false) String parentId) { return Result.success(typeService.getChildrenByParentId(parentId)); } @@ -88,7 +88,7 @@ public class ExpenseTypeController { * 删除支出类型 */ @DeleteMapping("/{id}") - public Result delete(@PathVariable Long id) { + public Result delete(@PathVariable String id) { return Result.success(typeService.deleteType(id)); } @@ -96,7 +96,7 @@ public class ExpenseTypeController { * 更新状态 */ @PutMapping("/{id}/status") - public Result updateStatus(@PathVariable Long id, @RequestParam Integer status) { + public Result updateStatus(@PathVariable String id, @RequestParam Integer status) { return Result.success(typeService.updateStatus(id, status)); } } diff --git a/fund-exp/src/main/java/com/fundplatform/exp/controller/FundExpenseController.java b/fund-exp/src/main/java/com/fundplatform/exp/controller/FundExpenseController.java index 39fc48d..bd97a76 100644 --- a/fund-exp/src/main/java/com/fundplatform/exp/controller/FundExpenseController.java +++ b/fund-exp/src/main/java/com/fundplatform/exp/controller/FundExpenseController.java @@ -38,7 +38,7 @@ public class FundExpenseController { * 创建支出申请 */ @PostMapping - public Result create(@Valid @RequestBody FundExpenseDTO dto) { + public Result create(@Valid @RequestBody FundExpenseDTO dto) { return Result.success(expenseService.createExpense(dto)); } @@ -46,7 +46,7 @@ public class FundExpenseController { * 更新支出申请(仅待审批状态可修改) */ @PutMapping("/{id}") - public Result update(@PathVariable Long id, @Valid @RequestBody FundExpenseDTO dto) { + public Result update(@PathVariable String id, @Valid @RequestBody FundExpenseDTO dto) { dto.setId(id); return Result.success(expenseService.updateExpense(dto)); } @@ -55,7 +55,7 @@ public class FundExpenseController { * 根据ID查询支出详情 */ @GetMapping("/{id}") - public Result getById(@PathVariable Long id) { + public Result getById(@PathVariable String id) { return Result.success(expenseService.getExpenseById(id)); } @@ -67,7 +67,7 @@ public class FundExpenseController { @RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize, @RequestParam(required = false) String title, - @RequestParam(required = false) Long expenseType, + @RequestParam(required = false) String expenseType, @RequestParam(required = false) Integer payStatus, @RequestParam(required = false) Integer approvalStatus) { Page page = expenseService.pageExpenses(pageNum, pageSize, title, expenseType, payStatus, approvalStatus); @@ -84,7 +84,7 @@ public class FundExpenseController { * 删除支出申请(仅待审批状态可删除) */ @DeleteMapping("/{id}") - public Result delete(@PathVariable Long id) { + public Result delete(@PathVariable String id) { return Result.success(expenseService.deleteExpense(id)); } @@ -92,7 +92,7 @@ public class FundExpenseController { * 提交审批(待审批 -> 审批中) */ @PostMapping("/{id}/submit") - public Result submitApproval(@PathVariable Long id) { + public Result submitApproval(@PathVariable String id) { return Result.success(expenseService.submitApproval(id)); } @@ -100,7 +100,7 @@ public class FundExpenseController { * 撤回审批(审批中 -> 待审批) */ @PostMapping("/{id}/withdraw") - public Result withdrawApproval(@PathVariable Long id) { + public Result withdrawApproval(@PathVariable String id) { return Result.success(expenseService.withdrawApproval(id)); } @@ -109,9 +109,9 @@ public class FundExpenseController { */ @PutMapping("/{id}/approve") public Result approve( - @PathVariable Long id, + @PathVariable String id, @RequestParam(required = false) String comment, - @RequestHeader(value = "X-User-Id", required = false) Long approverId) { + @RequestHeader(value = "X-User-Id", required = false) String approverId) { return Result.success(expenseService.approve(id, approverId, comment)); } @@ -120,9 +120,9 @@ public class FundExpenseController { */ @PutMapping("/{id}/reject") public Result reject( - @PathVariable Long id, + @PathVariable String id, @RequestParam(required = false) String comment, - @RequestHeader(value = "X-User-Id", required = false) Long approverId) { + @RequestHeader(value = "X-User-Id", required = false) String approverId) { return Result.success(expenseService.reject(id, approverId, comment)); } @@ -131,7 +131,7 @@ public class FundExpenseController { */ @PutMapping("/{id}/confirm-pay") public Result confirmPay( - @PathVariable Long id, + @PathVariable String id, @RequestParam String payChannel, @RequestParam(required = false) String payVoucher) { return Result.success(expenseService.confirmPay(id, payChannel, payVoucher)); @@ -141,7 +141,7 @@ public class FundExpenseController { * 标记支付失败 */ @PutMapping("/{id}/pay-failed") - public Result payFailed(@PathVariable Long id, @RequestParam String reason) { + public Result payFailed(@PathVariable String id, @RequestParam String reason) { return Result.success(expenseService.payFailed(id, reason)); } @@ -185,7 +185,7 @@ public class FundExpenseController { @GetMapping("/export") public void exportExcel( @RequestParam(required = false) String title, - @RequestParam(required = false) Long expenseType, + @RequestParam(required = false) String expenseType, @RequestParam(required = false) Integer payStatus, @RequestParam(required = false) Integer approvalStatus, HttpServletResponse response) { diff --git a/fund-exp/src/main/java/com/fundplatform/exp/dto/FundExpenseDTO.java b/fund-exp/src/main/java/com/fundplatform/exp/dto/FundExpenseDTO.java index d11174d..39b1e71 100644 --- a/fund-exp/src/main/java/com/fundplatform/exp/dto/FundExpenseDTO.java +++ b/fund-exp/src/main/java/com/fundplatform/exp/dto/FundExpenseDTO.java @@ -9,7 +9,7 @@ import java.time.LocalDateTime; public class FundExpenseDTO { - private Long id; + private String id; @NotBlank(message = "支出标题不能为空") private String title; @@ -20,8 +20,8 @@ public class FundExpenseDTO { private String currency = "CNY"; - @NotNull(message = "支出类型不能为空") - private Long expenseType; + @NotBlank(message = "支出类型不能为空") + private String expenseType; @NotBlank(message = "收款单位不能为空") private String payeeName; @@ -30,23 +30,23 @@ public class FundExpenseDTO { private String payeeAccount; private LocalDateTime expenseDate; private String purpose; - private Long requestId; - private Long projectId; - private Long customerId; + private String requestId; + private String projectId; + private String customerId; private String attachments; private String remark; // getters and setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public String getId() { return id; } + public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public BigDecimal getAmount() { return amount; } public void setAmount(BigDecimal amount) { this.amount = amount; } public String getCurrency() { return currency; } public void setCurrency(String currency) { this.currency = currency; } - public Long getExpenseType() { return expenseType; } - public void setExpenseType(Long expenseType) { this.expenseType = expenseType; } + public String getExpenseType() { return expenseType; } + public void setExpenseType(String expenseType) { this.expenseType = expenseType; } public String getPayeeName() { return payeeName; } public void setPayeeName(String payeeName) { this.payeeName = payeeName; } public String getPayeeBank() { return payeeBank; } @@ -57,12 +57,12 @@ public class FundExpenseDTO { public void setExpenseDate(LocalDateTime expenseDate) { this.expenseDate = expenseDate; } public String getPurpose() { return purpose; } public void setPurpose(String purpose) { this.purpose = purpose; } - public Long getRequestId() { return requestId; } - public void setRequestId(Long requestId) { this.requestId = requestId; } - public Long getProjectId() { return projectId; } - public void setProjectId(Long projectId) { this.projectId = projectId; } - public Long getCustomerId() { return customerId; } - public void setCustomerId(Long customerId) { this.customerId = customerId; } + public String getRequestId() { return requestId; } + public void setRequestId(String requestId) { this.requestId = requestId; } + public String getProjectId() { return projectId; } + public void setProjectId(String projectId) { this.projectId = projectId; } + public String getCustomerId() { return customerId; } + public void setCustomerId(String customerId) { this.customerId = customerId; } public String getAttachments() { return attachments; } public void setAttachments(String attachments) { this.attachments = attachments; } public String getRemark() { return remark; } diff --git a/fund-exp/src/main/java/com/fundplatform/exp/service/FundExpenseService.java b/fund-exp/src/main/java/com/fundplatform/exp/service/FundExpenseService.java index 898d3c0..45d5a0b 100644 --- a/fund-exp/src/main/java/com/fundplatform/exp/service/FundExpenseService.java +++ b/fund-exp/src/main/java/com/fundplatform/exp/service/FundExpenseService.java @@ -6,50 +6,50 @@ import com.fundplatform.exp.vo.FundExpenseVO; public interface FundExpenseService { - Long createExpense(FundExpenseDTO dto); + String createExpense(FundExpenseDTO dto); boolean updateExpense(FundExpenseDTO dto); - FundExpenseVO getExpenseById(Long id); + FundExpenseVO getExpenseById(String id); - Page pageExpenses(int pageNum, int pageSize, String title, Long expenseType, Integer payStatus, Integer approvalStatus); + Page pageExpenses(int pageNum, int pageSize, String title, String expenseType, Integer payStatus, Integer approvalStatus); /** * 查询支出列表(不分页,用于导出) */ - java.util.List listExpenses(String title, Long expenseType, Integer payStatus, Integer approvalStatus); + java.util.List listExpenses(String title, String expenseType, Integer payStatus, Integer approvalStatus); - boolean deleteExpense(Long id); + boolean deleteExpense(String id); /** * 提交审批(待审批 -> 审批中) */ - boolean submitApproval(Long id); + boolean submitApproval(String id); /** * 审批通过(审批中 -> 审批通过) */ - boolean approve(Long id, Long approverId, String comment); + boolean approve(String id, String approverId, String comment); /** * 审批拒绝(审批中 -> 审批拒绝) */ - boolean reject(Long id, Long approverId, String comment); + boolean reject(String id, String approverId, String comment); /** * 撤回审批(审批中 -> 待审批) */ - boolean withdrawApproval(Long id); + boolean withdrawApproval(String id); /** * 确认支付(审批通过后才能支付) */ - boolean confirmPay(Long id, String payChannel, String payVoucher); + boolean confirmPay(String id, String payChannel, String payVoucher); /** * 支付失败 */ - boolean payFailed(Long id, String reason); + boolean payFailed(String id, String reason); // ===================== 统计相关 ===================== diff --git a/fund-exp/src/main/java/com/fundplatform/exp/service/impl/FundExpenseServiceImpl.java b/fund-exp/src/main/java/com/fundplatform/exp/service/impl/FundExpenseServiceImpl.java index 43c3058..eb42801 100644 --- a/fund-exp/src/main/java/com/fundplatform/exp/service/impl/FundExpenseServiceImpl.java +++ b/fund-exp/src/main/java/com/fundplatform/exp/service/impl/FundExpenseServiceImpl.java @@ -56,7 +56,7 @@ public class FundExpenseServiceImpl implements FundExpenseService { @Override @Transactional(rollbackFor = Exception.class) - public Long createExpense(FundExpenseDTO dto) { + public String createExpense(FundExpenseDTO dto) { FundExpense expense = new FundExpense(); expense.setExpenseNo(generateExpenseNo()); expense.setTitle(dto.getTitle()); @@ -78,10 +78,10 @@ public class FundExpenseServiceImpl implements FundExpenseService { expense.setCreatedTime(LocalDateTime.now()); // 获取租户ID和用户ID,如果没有则使用默认值 - Long tenantId = TenantContextHolder.getTenantId(); - expense.setTenantId(tenantId != null ? tenantId : 1L); - Long userId = UserContextHolder.getUserId(); - expense.setCreatedBy(userId != null ? userId : 1L); + String tenantId = TenantContextHolder.getTenantId(); + expense.setTenantId(tenantId != null ? tenantId : "1"); + String userId = UserContextHolder.getUserId(); + expense.setCreatedBy(userId != null ? userId : "1"); expenseDataService.save(expense); log.info("创建支出记录成功: id={}, expenseNo={}", expense.getId(), expense.getExpenseNo()); @@ -112,14 +112,14 @@ public class FundExpenseServiceImpl implements FundExpenseService { } @Override - public FundExpenseVO getExpenseById(Long id) { + public FundExpenseVO getExpenseById(String id) { FundExpense expense = expenseDataService.getById(id); if (expense == null || expense.getDeleted() == 1) throw new RuntimeException("支出记录不存在"); return convertToVO(expense); } @Override - public Page pageExpenses(int pageNum, int pageSize, String title, Long expenseType, Integer payStatus, Integer approvalStatus) { + public Page pageExpenses(int pageNum, int pageSize, String title, String expenseType, Integer payStatus, Integer approvalStatus) { Page page = new Page<>(pageNum, pageSize); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(FundExpense::getDeleted, 0); @@ -136,7 +136,7 @@ public class FundExpenseServiceImpl implements FundExpenseService { } @Override - public List listExpenses(String title, Long expenseType, Integer payStatus, Integer approvalStatus) { + public List listExpenses(String title, String expenseType, Integer payStatus, Integer approvalStatus) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(FundExpense::getDeleted, 0); if (StringUtils.hasText(title)) wrapper.like(FundExpense::getTitle, title); @@ -150,7 +150,7 @@ public class FundExpenseServiceImpl implements FundExpenseService { @Override @Transactional(rollbackFor = Exception.class) - public boolean deleteExpense(Long id) { + public boolean deleteExpense(String id) { FundExpense existing = expenseDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("支出记录不存在"); @@ -170,7 +170,7 @@ public class FundExpenseServiceImpl implements FundExpenseService { @Override @Transactional(rollbackFor = Exception.class) - public boolean submitApproval(Long id) { + public boolean submitApproval(String id) { FundExpense existing = expenseDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("支出记录不存在"); @@ -195,7 +195,7 @@ public class FundExpenseServiceImpl implements FundExpenseService { @Override @Transactional(rollbackFor = Exception.class) - public boolean approve(Long id, Long approverId, String comment) { + public boolean approve(String id, String approverId, String comment) { FundExpense existing = expenseDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("支出记录不存在"); @@ -223,7 +223,7 @@ public class FundExpenseServiceImpl implements FundExpenseService { @Override @Transactional(rollbackFor = Exception.class) - public boolean reject(Long id, Long approverId, String comment) { + public boolean reject(String id, String approverId, String comment) { FundExpense existing = expenseDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("支出记录不存在"); @@ -251,7 +251,7 @@ public class FundExpenseServiceImpl implements FundExpenseService { @Override @Transactional(rollbackFor = Exception.class) - public boolean withdrawApproval(Long id) { + public boolean withdrawApproval(String id) { FundExpense existing = expenseDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("支出记录不存在"); @@ -276,7 +276,7 @@ public class FundExpenseServiceImpl implements FundExpenseService { @Override @Transactional(rollbackFor = Exception.class) - public boolean confirmPay(Long id, String payChannel, String payVoucher) { + public boolean confirmPay(String id, String payChannel, String payVoucher) { FundExpense existing = expenseDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("支出记录不存在"); @@ -307,7 +307,7 @@ public class FundExpenseServiceImpl implements FundExpenseService { @Override @Transactional(rollbackFor = Exception.class) - public boolean payFailed(Long id, String reason) { + public boolean payFailed(String id, String reason) { FundExpense existing = expenseDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("支出记录不存在"); @@ -371,9 +371,14 @@ public class FundExpenseServiceImpl implements FundExpenseService { return vo; } - private String getExpenseTypeName(Long type) { - if (type == null) return ""; - return switch (type.intValue()) { case 1 -> "日常支出"; case 2 -> "项目支出"; case 3 -> "工资发放"; case 4 -> "其他"; default -> ""; }; + private String getExpenseTypeName(String type) { + if (type == null || type.isEmpty()) return ""; + try { + int typeValue = Integer.parseInt(type); + return switch (typeValue) { case 1 -> "日常支出"; case 2 -> "项目支出"; case 3 -> "工资发放"; case 4 -> "其他"; default -> ""; }; + } catch (NumberFormatException e) { + return ""; + } } private String getPayStatusName(Integer status) { @@ -447,19 +452,19 @@ public class FundExpenseServiceImpl implements FundExpenseService { List expenses = expenseDataService.list(wrapper); - Map typeAmountMap = new HashMap<>(); - Map typeCountMap = new HashMap<>(); + Map typeAmountMap = new HashMap<>(); + Map typeCountMap = new HashMap<>(); for (FundExpense expense : expenses) { - Long type = expense.getExpenseType(); - if (type == null) type = 0L; + String type = expense.getExpenseType(); + if (type == null) type = "0"; typeAmountMap.merge(type, expense.getAmount() != null ? expense.getAmount() : BigDecimal.ZERO, BigDecimal::add); typeCountMap.merge(type, 1, Integer::sum); } List> result = new ArrayList<>(); - for (Long type : typeAmountMap.keySet()) { + for (String type : typeAmountMap.keySet()) { Map item = new HashMap<>(); item.put("type", type); item.put("name", getExpenseTypeName(type)); diff --git a/fund-exp/src/main/java/com/fundplatform/exp/vo/FundExpenseVO.java b/fund-exp/src/main/java/com/fundplatform/exp/vo/FundExpenseVO.java index 1d12d3a..d5542c8 100644 --- a/fund-exp/src/main/java/com/fundplatform/exp/vo/FundExpenseVO.java +++ b/fund-exp/src/main/java/com/fundplatform/exp/vo/FundExpenseVO.java @@ -8,26 +8,21 @@ import java.time.LocalDateTime; public class FundExpenseVO { - @JsonSerialize(using = ToStringSerializer.class) - private Long id; + private String id; private String expenseNo; private String title; private BigDecimal amount; private String currency; - @JsonSerialize(using = ToStringSerializer.class) - private Long expenseType; + private String expenseType; private String expenseTypeName; private String payeeName; private String payeeBank; private String payeeAccount; private LocalDateTime expenseDate; private String purpose; - @JsonSerialize(using = ToStringSerializer.class) - private Long requestId; - @JsonSerialize(using = ToStringSerializer.class) - private Long projectId; - @JsonSerialize(using = ToStringSerializer.class) - private Long customerId; + private String requestId; + private String projectId; + private String customerId; private Integer payStatus; private String payStatusName; private LocalDateTime payTime; @@ -35,20 +30,17 @@ public class FundExpenseVO { private String payVoucher; private Integer approvalStatus; private String approvalStatusName; - @JsonSerialize(using = ToStringSerializer.class) - private Long approverId; + private String approverId; private LocalDateTime approvalTime; private String approvalComment; private String attachments; - @JsonSerialize(using = ToStringSerializer.class) - private Long tenantId; - @JsonSerialize(using = ToStringSerializer.class) - private Long createdBy; + private String tenantId; + private String createdBy; private LocalDateTime createdTime; // getters and setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public String getId() { return id; } + public void setId(String id) { this.id = id; } public String getExpenseNo() { return expenseNo; } public void setExpenseNo(String expenseNo) { this.expenseNo = expenseNo; } public String getTitle() { return title; } @@ -57,8 +49,8 @@ public class FundExpenseVO { public void setAmount(BigDecimal amount) { this.amount = amount; } public String getCurrency() { return currency; } public void setCurrency(String currency) { this.currency = currency; } - public Long getExpenseType() { return expenseType; } - public void setExpenseType(Long expenseType) { this.expenseType = expenseType; } + public String getExpenseType() { return expenseType; } + public void setExpenseType(String expenseType) { this.expenseType = expenseType; } public String getExpenseTypeName() { return expenseTypeName; } public void setExpenseTypeName(String expenseTypeName) { this.expenseTypeName = expenseTypeName; } public String getPayeeName() { return payeeName; } @@ -71,12 +63,12 @@ public class FundExpenseVO { public void setExpenseDate(LocalDateTime expenseDate) { this.expenseDate = expenseDate; } public String getPurpose() { return purpose; } public void setPurpose(String purpose) { this.purpose = purpose; } - public Long getRequestId() { return requestId; } - public void setRequestId(Long requestId) { this.requestId = requestId; } - public Long getProjectId() { return projectId; } - public void setProjectId(Long projectId) { this.projectId = projectId; } - public Long getCustomerId() { return customerId; } - public void setCustomerId(Long customerId) { this.customerId = customerId; } + public String getRequestId() { return requestId; } + public void setRequestId(String requestId) { this.requestId = requestId; } + public String getProjectId() { return projectId; } + public void setProjectId(String projectId) { this.projectId = projectId; } + public String getCustomerId() { return customerId; } + public void setCustomerId(String customerId) { this.customerId = customerId; } public Integer getPayStatus() { return payStatus; } public void setPayStatus(Integer payStatus) { this.payStatus = payStatus; } public String getPayStatusName() { return payStatusName; } @@ -91,18 +83,18 @@ public class FundExpenseVO { public void setApprovalStatus(Integer approvalStatus) { this.approvalStatus = approvalStatus; } public String getApprovalStatusName() { return approvalStatusName; } public void setApprovalStatusName(String approvalStatusName) { this.approvalStatusName = approvalStatusName; } - public Long getApproverId() { return approverId; } - public void setApproverId(Long approverId) { this.approverId = approverId; } + public String getApproverId() { return approverId; } + public void setApproverId(String approverId) { this.approverId = approverId; } public LocalDateTime getApprovalTime() { return approvalTime; } public void setApprovalTime(LocalDateTime approvalTime) { this.approvalTime = approvalTime; } public String getApprovalComment() { return approvalComment; } public void setApprovalComment(String approvalComment) { this.approvalComment = approvalComment; } public String getAttachments() { return attachments; } public void setAttachments(String attachments) { this.attachments = attachments; } - public Long getTenantId() { return tenantId; } - public void setTenantId(Long tenantId) { this.tenantId = tenantId; } - public Long getCreatedBy() { return createdBy; } - public void setCreatedBy(Long createdBy) { this.createdBy = createdBy; } + public String getTenantId() { return tenantId; } + public void setTenantId(String tenantId) { this.tenantId = tenantId; } + public String getCreatedBy() { return createdBy; } + public void setCreatedBy(String createdBy) { this.createdBy = createdBy; } public LocalDateTime getCreatedTime() { return createdTime; } public void setCreatedTime(LocalDateTime createdTime) { this.createdTime = createdTime; } } diff --git a/fund-file/src/main/java/com/fundplatform/file/controller/FileController.java b/fund-file/src/main/java/com/fundplatform/file/controller/FileController.java index b995d96..5b3d48c 100644 --- a/fund-file/src/main/java/com/fundplatform/file/controller/FileController.java +++ b/fund-file/src/main/java/com/fundplatform/file/controller/FileController.java @@ -55,10 +55,10 @@ public class FileController { public Result upload( @RequestParam("file") MultipartFile file, @RequestParam(value = "businessType", required = false) String businessType, - @RequestParam(value = "businessId", required = false) Long businessId, + @RequestParam(value = "businessId", required = false) String businessId, @RequestParam(value = "description", required = false) String description, - @RequestHeader(value = "X-Tenant-Id", required = false) Long tenantId, - @RequestHeader(value = "X-User-Id", required = false) Long userId) { + @RequestHeader(value = "X-Tenant-Id", required = false) String tenantId, + @RequestHeader(value = "X-User-Id", required = false) String userId) { if (file.isEmpty()) { return Result.error("请选择要上传的文件"); @@ -111,7 +111,7 @@ public class FileController { // 创建文件记录 FileRecord record = new FileRecord(); - record.setTenantId(tenantId != null ? tenantId : 1L); + record.setTenantId(tenantId != null ? tenantId : "default"); record.setFileName(originalFilename); record.setFilePath(filePath); record.setFileUrl(fileUrl); @@ -124,7 +124,7 @@ public class FileController { record.setDescription(description); record.setCreatedBy(userId); - Long fileId = fileRecordService.createFileRecord(record); + String fileId = fileRecordService.createFileRecord(record); // 返回VO FileRecordVO vo = new FileRecordVO(); @@ -154,7 +154,7 @@ public class FileController { */ @GetMapping("/download/**") public void download(HttpServletResponse response, - @RequestHeader(value = "X-Tenant-Id", required = false) Long tenantId) throws IOException { + @RequestHeader(value = "X-Tenant-Id", required = false) String tenantId) throws IOException { String requestUri = request.getRequestURI(); String filePath = requestUri.substring(requestUri.indexOf("/download/") + 10); String fullPath = uploadPath + "/" + filePath; @@ -194,7 +194,7 @@ public class FileController { * 根据ID获取文件信息 */ @GetMapping("/{id}") - public Result getById(@PathVariable Long id) { + public Result getById(@PathVariable String id) { FileRecord record = fileRecordService.getById(id); if (record == null) { return Result.error("文件不存在"); @@ -210,7 +210,7 @@ public class FileController { @RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize, @RequestParam(required = false) String businessType, - @RequestParam(required = false) Long businessId, + @RequestParam(required = false) String businessId, @RequestParam(required = false) String fileType) { Page page = fileRecordService.page(pageNum, pageSize, businessType, businessId, fileType); @@ -231,7 +231,7 @@ public class FileController { @GetMapping("/list") public Result> listByBusiness( @RequestParam String businessType, - @RequestParam Long businessId) { + @RequestParam String businessId) { List records = fileRecordService.listByBusiness(businessType, businessId); List voList = new ArrayList<>(); @@ -245,7 +245,7 @@ public class FileController { * 删除文件 */ @DeleteMapping("/{id}") - public Result delete(@PathVariable Long id) { + public Result delete(@PathVariable String id) { FileRecord record = fileRecordService.getById(id); if (record == null) { return Result.error("文件不存在"); diff --git a/fund-file/src/main/java/com/fundplatform/file/data/service/FileRecordService.java b/fund-file/src/main/java/com/fundplatform/file/data/service/FileRecordService.java index 1e5c070..14ca767 100644 --- a/fund-file/src/main/java/com/fundplatform/file/data/service/FileRecordService.java +++ b/fund-file/src/main/java/com/fundplatform/file/data/service/FileRecordService.java @@ -28,7 +28,7 @@ public class FileRecordService { * 创建文件记录 */ @Transactional - public Long createFileRecord(FileRecord record) { + public String createFileRecord(FileRecord record) { record.setDownloadCount(0); record.setStatus(1); record.setCreatedTime(LocalDateTime.now()); @@ -39,14 +39,14 @@ public class FileRecordService { /** * 根据ID查询 */ - public FileRecord getById(Long id) { + public FileRecord getById(String id) { return fileRecordMapper.selectById(id); } /** * 分页查询 */ - public Page page(int pageNum, int pageSize, String businessType, Long businessId, String fileType) { + public Page page(int pageNum, int pageSize, String businessType, String businessId, String fileType) { Page page = new Page<>(pageNum, pageSize); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(businessType != null, FileRecord::getBusinessType, businessType); @@ -59,7 +59,7 @@ public class FileRecordService { /** * 根据业务类型和ID查询 */ - public List listByBusiness(String businessType, Long businessId) { + public List listByBusiness(String businessType, String businessId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(FileRecord::getBusinessType, businessType); wrapper.eq(FileRecord::getBusinessId, businessId); @@ -80,7 +80,7 @@ public class FileRecordService { * 增加下载次数 */ @Transactional - public boolean incrementDownloadCount(Long id) { + public boolean incrementDownloadCount(String id) { FileRecord record = fileRecordMapper.selectById(id); if (record != null) { record.setDownloadCount(record.getDownloadCount() + 1); @@ -93,7 +93,7 @@ public class FileRecordService { * 删除文件记录 */ @Transactional - public boolean deleteFileRecord(Long id) { + public boolean deleteFileRecord(String id) { return fileRecordMapper.deleteById(id) > 0; } diff --git a/fund-file/src/main/java/com/fundplatform/file/vo/FileRecordVO.java b/fund-file/src/main/java/com/fundplatform/file/vo/FileRecordVO.java index 6ae118e..4cb9a4a 100644 --- a/fund-file/src/main/java/com/fundplatform/file/vo/FileRecordVO.java +++ b/fund-file/src/main/java/com/fundplatform/file/vo/FileRecordVO.java @@ -7,9 +7,9 @@ import java.time.LocalDateTime; */ public class FileRecordVO { - private Long fileId; + private String fileId; - private Long tenantId; + private String tenantId; private String fileName; @@ -27,7 +27,7 @@ public class FileRecordVO { private String businessType; - private Long businessId; + private String businessId; private String description; @@ -35,25 +35,25 @@ public class FileRecordVO { private Integer status; - private Long createdBy; + private String createdBy; private String createdByName; private LocalDateTime createdTime; - public Long getFileId() { + public String getFileId() { return fileId; } - public void setFileId(Long fileId) { + public void setFileId(String fileId) { this.fileId = fileId; } - public Long getTenantId() { + public String getTenantId() { return tenantId; } - public void setTenantId(Long tenantId) { + public void setTenantId(String tenantId) { this.tenantId = tenantId; } @@ -121,11 +121,11 @@ public class FileRecordVO { this.businessType = businessType; } - public Long getBusinessId() { + public String getBusinessId() { return businessId; } - public void setBusinessId(Long businessId) { + public void setBusinessId(String businessId) { this.businessId = businessId; } @@ -153,11 +153,11 @@ public class FileRecordVO { this.status = status; } - public Long getCreatedBy() { + public String getCreatedBy() { return createdBy; } - public void setCreatedBy(Long createdBy) { + public void setCreatedBy(String createdBy) { this.createdBy = createdBy; } diff --git a/fund-proj/src/main/java/com/fundplatform/proj/controller/RequirementController.java b/fund-proj/src/main/java/com/fundplatform/proj/controller/RequirementController.java index cc0b88e..2432e55 100644 --- a/fund-proj/src/main/java/com/fundplatform/proj/controller/RequirementController.java +++ b/fund-proj/src/main/java/com/fundplatform/proj/controller/RequirementController.java @@ -24,7 +24,7 @@ public class RequirementController { */ @GetMapping("/page") public Result> page( - @RequestHeader(value = "X-Tenant-Id", required = false) Long tenantId, + @RequestHeader(value = "X-Tenant-Id", required = false) String tenantId, @RequestParam(required = false) String requirementName, @RequestParam(required = false) String projectName, @RequestParam(required = false) String requirementStatus, @@ -39,8 +39,8 @@ public class RequirementController { */ @GetMapping("/{requirementId}") public Result get( - @RequestHeader("X-Tenant-Id") Long tenantId, - @PathVariable Long requirementId) { + @RequestHeader("X-Tenant-Id") String tenantId, + @PathVariable String requirementId) { return requirementService.getById(tenantId, requirementId); } diff --git a/fund-proj/src/main/java/com/fundplatform/proj/dto/RequirementDTO.java b/fund-proj/src/main/java/com/fundplatform/proj/dto/RequirementDTO.java index a2a94d7..de582ba 100644 --- a/fund-proj/src/main/java/com/fundplatform/proj/dto/RequirementDTO.java +++ b/fund-proj/src/main/java/com/fundplatform/proj/dto/RequirementDTO.java @@ -11,7 +11,7 @@ import java.time.LocalDate; */ public class RequirementDTO { - private Long requirementId; + private String requirementId; @NotBlank(message = "需求编号不能为空") private String requirementCode; @@ -21,11 +21,11 @@ public class RequirementDTO { private String description; - @NotNull(message = "项目ID不能为空") - private Long projectId; + @NotBlank(message = "项目ID不能为空") + private String projectId; - @NotNull(message = "客户ID不能为空") - private Long customerId; + @NotBlank(message = "客户ID不能为空") + private String customerId; private String priority; @@ -53,11 +53,11 @@ public class RequirementDTO { private String attachmentUrl; - public Long getRequirementId() { + public String getRequirementId() { return requirementId; } - public void setRequirementId(Long requirementId) { + public void setRequirementId(String requirementId) { this.requirementId = requirementId; } @@ -85,19 +85,19 @@ public class RequirementDTO { this.description = description; } - public Long getProjectId() { + public String getProjectId() { return projectId; } - public void setProjectId(Long projectId) { + public void setProjectId(String projectId) { this.projectId = projectId; } - public Long getCustomerId() { + public String getCustomerId() { return customerId; } - public void setCustomerId(Long customerId) { + public void setCustomerId(String customerId) { this.customerId = customerId; } diff --git a/fund-proj/src/main/java/com/fundplatform/proj/service/RequirementService.java b/fund-proj/src/main/java/com/fundplatform/proj/service/RequirementService.java index 42ae32f..00287fd 100644 --- a/fund-proj/src/main/java/com/fundplatform/proj/service/RequirementService.java +++ b/fund-proj/src/main/java/com/fundplatform/proj/service/RequirementService.java @@ -47,8 +47,8 @@ public class RequirementService { /** * 分页查询需求工单 */ - public Result> page(Long tenantId, String requirementName, String status, - Long projectId, Long customerId, int current, int size) { + public Result> page(String tenantId, String requirementName, String status, + String projectId, String customerId, int current, int size) { Page page = new Page<>(current, size); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Requirement::getTenantId, tenantId); @@ -80,7 +80,7 @@ public class RequirementService { /** * 查询需求工单详情 */ - public Result getById(Long tenantId, Long requirementId) { + public Result getById(String tenantId, String requirementId) { Requirement requirement = requirementDataService.getOne( new LambdaQueryWrapper() .eq(Requirement::getId, requirementId) diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/service/FundReceiptService.java b/fund-receipt/src/main/java/com/fundplatform/receipt/service/FundReceiptService.java index 18dcd76..0e428bd 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/service/FundReceiptService.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/service/FundReceiptService.java @@ -8,22 +8,22 @@ import java.util.List; public interface FundReceiptService { - Long createReceipt(FundReceiptDTO dto); + String createReceipt(FundReceiptDTO dto); boolean updateReceipt(FundReceiptDTO dto); - FundReceiptVO getReceiptById(Long id); + FundReceiptVO getReceiptById(String id); Page pageReceipts(int pageNum, int pageSize, String title, Integer receiptType, Integer receiptStatus); /** * 根据应收款ID查询收款记录 */ - List getReceiptsByReceivableId(Long receivableId); + List getReceiptsByReceivableId(String receivableId); - boolean deleteReceipt(Long id); + boolean deleteReceipt(String id); - boolean confirm(Long id); + boolean confirm(String id); - boolean writeOff(Long id); + boolean writeOff(String id); } diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/service/ReceivableService.java b/fund-receipt/src/main/java/com/fundplatform/receipt/service/ReceivableService.java index 47fe69c..090bf6f 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/service/ReceivableService.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/service/ReceivableService.java @@ -16,7 +16,7 @@ public interface ReceivableService { /** * 创建应收款 */ - Long createReceivable(ReceivableDTO dto); + String createReceivable(ReceivableDTO dto); /** * 更新应收款 @@ -26,37 +26,37 @@ public interface ReceivableService { /** * 根据ID查询应收款 */ - ReceivableVO getReceivableById(Long id); + ReceivableVO getReceivableById(String id); /** * 分页查询应收款 */ - Page pageReceivables(int pageNum, int pageSize, Long projectId, Long customerId, String status, Integer confirmStatus); + Page pageReceivables(int pageNum, int pageSize, String projectId, String customerId, String status, Integer confirmStatus); /** * 查询应收款列表(不分页,用于导出) */ - List listReceivables(Long projectId, Long customerId, String status, Integer confirmStatus); + List listReceivables(String projectId, String customerId, String status, Integer confirmStatus); /** * 确认应收款 */ - boolean confirmReceivable(Long id, Long confirmBy); + boolean confirmReceivable(String id, String confirmBy); /** * 取消确认 */ - boolean cancelConfirm(Long id); + boolean cancelConfirm(String id); /** * 记录收款(更新已收款金额) */ - boolean recordReceipt(Long id, BigDecimal amount); + boolean recordReceipt(String id, BigDecimal amount); /** * 获取应收款的收款记录 */ - List getReceiptsByReceivableId(Long receivableId); + List getReceiptsByReceivableId(String receivableId); /** * 更新逾期状态 @@ -66,7 +66,7 @@ public interface ReceivableService { /** * 删除应收款 */ - boolean deleteReceivable(Long id); + boolean deleteReceivable(String id); // ===================== 统计相关 ===================== diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/FundReceiptServiceImpl.java b/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/FundReceiptServiceImpl.java index 431169d..372820c 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/FundReceiptServiceImpl.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/FundReceiptServiceImpl.java @@ -34,7 +34,7 @@ public class FundReceiptServiceImpl implements FundReceiptService { @Override @Transactional(rollbackFor = Exception.class) - public Long createReceipt(FundReceiptDTO dto) { + public String createReceipt(FundReceiptDTO dto) { FundReceipt receipt = new FundReceipt(); receipt.setReceiptNo(generateReceiptNo()); receipt.setTitle(dto.getTitle()); @@ -80,7 +80,7 @@ public class FundReceiptServiceImpl implements FundReceiptService { } @Override - public FundReceiptVO getReceiptById(Long id) { + public FundReceiptVO getReceiptById(String id) { FundReceipt receipt = receiptDataService.getById(id); if (receipt == null || receipt.getDeleted() == 1) throw new RuntimeException("收款记录不存在"); return convertToVO(receipt); @@ -103,7 +103,7 @@ public class FundReceiptServiceImpl implements FundReceiptService { } @Override - public List getReceiptsByReceivableId(Long receivableId) { + public List getReceiptsByReceivableId(String receivableId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(FundReceipt::getDeleted, 0); wrapper.eq(FundReceipt::getReceivableId, receivableId); @@ -113,7 +113,7 @@ public class FundReceiptServiceImpl implements FundReceiptService { @Override @Transactional(rollbackFor = Exception.class) - public boolean deleteReceipt(Long id) { + public boolean deleteReceipt(String id) { LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); wrapper.eq(FundReceipt::getId, id).set(FundReceipt::getDeleted, 1).set(FundReceipt::getUpdatedTime, LocalDateTime.now()); return receiptDataService.update(wrapper); @@ -121,7 +121,7 @@ public class FundReceiptServiceImpl implements FundReceiptService { @Override @Transactional(rollbackFor = Exception.class) - public boolean confirm(Long id) { + public boolean confirm(String id) { LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); wrapper.eq(FundReceipt::getId, id).set(FundReceipt::getReceiptStatus, 1) .set(FundReceipt::getConfirmTime, LocalDateTime.now()) @@ -131,7 +131,7 @@ public class FundReceiptServiceImpl implements FundReceiptService { @Override @Transactional(rollbackFor = Exception.class) - public boolean writeOff(Long id) { + public boolean writeOff(String id) { LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); wrapper.eq(FundReceipt::getId, id).set(FundReceipt::getReceiptStatus, 2) .set(FundReceipt::getWriteOffTime, LocalDateTime.now()) diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/ReceivableServiceImpl.java b/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/ReceivableServiceImpl.java index 71becb3..7e3424f 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/ReceivableServiceImpl.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/ReceivableServiceImpl.java @@ -54,7 +54,7 @@ public class ReceivableServiceImpl implements ReceivableService { @Override @Transactional(rollbackFor = Exception.class) - public Long createReceivable(ReceivableDTO dto) { + public String createReceivable(ReceivableDTO dto) { Receivable receivable = new Receivable(); receivable.setReceivableCode(generateReceivableCode()); receivable.setRequirementId(dto.getRequirementId()); @@ -112,7 +112,7 @@ public class ReceivableServiceImpl implements ReceivableService { } @Override - public ReceivableVO getReceivableById(Long id) { + public ReceivableVO getReceivableById(String id) { Receivable receivable = receivableDataService.getById(id); if (receivable == null || receivable.getDeleted() == 1) { throw new RuntimeException("应收款不存在"); @@ -121,7 +121,7 @@ public class ReceivableServiceImpl implements ReceivableService { } @Override - public Page pageReceivables(int pageNum, int pageSize, Long projectId, Long customerId, String status, Integer confirmStatus) { + public Page pageReceivables(int pageNum, int pageSize, String projectId, String customerId, String status, Integer confirmStatus) { Page page = new Page<>(pageNum, pageSize); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Receivable::getDeleted, 0); @@ -138,7 +138,7 @@ public class ReceivableServiceImpl implements ReceivableService { } @Override - public List listReceivables(Long projectId, Long customerId, String status, Integer confirmStatus) { + public List listReceivables(String projectId, String customerId, String status, Integer confirmStatus) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Receivable::getDeleted, 0); if (projectId != null) wrapper.eq(Receivable::getProjectId, projectId); @@ -152,7 +152,7 @@ public class ReceivableServiceImpl implements ReceivableService { @Override @Transactional(rollbackFor = Exception.class) - public boolean confirmReceivable(Long id, Long confirmBy) { + public boolean confirmReceivable(String id, String confirmBy) { Receivable existing = receivableDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("应收款不存在"); @@ -178,7 +178,7 @@ public class ReceivableServiceImpl implements ReceivableService { @Override @Transactional(rollbackFor = Exception.class) - public boolean cancelConfirm(Long id) { + public boolean cancelConfirm(String id) { Receivable existing = receivableDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("应收款不存在"); @@ -207,7 +207,7 @@ public class ReceivableServiceImpl implements ReceivableService { @Override @Transactional(rollbackFor = Exception.class) - public boolean recordReceipt(Long id, BigDecimal amount) { + public boolean recordReceipt(String id, BigDecimal amount) { Receivable existing = receivableDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("应收款不存在"); @@ -248,7 +248,7 @@ public class ReceivableServiceImpl implements ReceivableService { } @Override - public List getReceiptsByReceivableId(Long receivableId) { + public List getReceiptsByReceivableId(String receivableId) { return receiptService.getReceiptsByReceivableId(receivableId); } @@ -279,7 +279,7 @@ public class ReceivableServiceImpl implements ReceivableService { @Override @Transactional(rollbackFor = Exception.class) - public boolean deleteReceivable(Long id) { + public boolean deleteReceivable(String id) { Receivable existing = receivableDataService.getById(id); if (existing == null || existing.getDeleted() == 1) { throw new RuntimeException("应收款不存在"); diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/vo/ReceivableVO.java b/fund-receipt/src/main/java/com/fundplatform/receipt/vo/ReceivableVO.java index 3c6a0d6..138421f 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/vo/ReceivableVO.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/vo/ReceivableVO.java @@ -9,12 +9,12 @@ import java.time.LocalDateTime; */ public class ReceivableVO { - private Long id; + private String id; private String receivableCode; - private Long requirementId; - private Long projectId; + private String requirementId; + private String projectId; private String projectName; - private Long customerId; + private String customerId; private String customerName; private BigDecimal receivableAmount; private BigDecimal receivedAmount; @@ -30,18 +30,18 @@ public class ReceivableVO { private Integer confirmStatus; private String confirmStatusName; private LocalDateTime confirmTime; - private Long confirmBy; - private Long tenantId; - private Long createdBy; + private String confirmBy; + private String tenantId; + private String createdBy; private LocalDateTime createdTime; private LocalDateTime updatedTime; private String remark; - public Long getId() { + public String getId() { return id; } - public void setId(Long id) { + public void setId(String id) { this.id = id; } @@ -53,19 +53,19 @@ public class ReceivableVO { this.receivableCode = receivableCode; } - public Long getRequirementId() { + public String getRequirementId() { return requirementId; } - public void setRequirementId(Long requirementId) { + public void setRequirementId(String requirementId) { this.requirementId = requirementId; } - public Long getProjectId() { + public String getProjectId() { return projectId; } - public void setProjectId(Long projectId) { + public void setProjectId(String projectId) { this.projectId = projectId; } @@ -77,11 +77,11 @@ public class ReceivableVO { this.projectName = projectName; } - public Long getCustomerId() { + public String getCustomerId() { return customerId; } - public void setCustomerId(Long customerId) { + public void setCustomerId(String customerId) { this.customerId = customerId; } @@ -205,27 +205,27 @@ public class ReceivableVO { this.confirmTime = confirmTime; } - public Long getConfirmBy() { + public String getConfirmBy() { return confirmBy; } - public void setConfirmBy(Long confirmBy) { + public void setConfirmBy(String confirmBy) { this.confirmBy = confirmBy; } - public Long getTenantId() { + public String getTenantId() { return tenantId; } - public void setTenantId(Long tenantId) { + public void setTenantId(String tenantId) { this.tenantId = tenantId; } - public Long getCreatedBy() { + public String getCreatedBy() { return createdBy; } - public void setCreatedBy(Long createdBy) { + public void setCreatedBy(String createdBy) { this.createdBy = createdBy; } diff --git a/fund-report/src/main/java/com/fundplatform/report/controller/ReportController.java b/fund-report/src/main/java/com/fundplatform/report/controller/ReportController.java index 8b06bd8..ea54916 100644 --- a/fund-report/src/main/java/com/fundplatform/report/controller/ReportController.java +++ b/fund-report/src/main/java/com/fundplatform/report/controller/ReportController.java @@ -66,8 +66,8 @@ public class ReportController { @GetMapping("/project/finance") public Result> getProjectFinance( @RequestParam(required = false) String status, - @RequestParam(required = false) Long customerId, - @RequestHeader(value = "X-Tenant-Id", required = false) Long tenantId) { + @RequestParam(required = false) String customerId, + @RequestHeader(value = "X-Tenant-Id", required = false) String tenantId) { return Result.success(reportService.getProjectFinance(tenantId, status, customerId)); } @@ -77,8 +77,8 @@ public class ReportController { @GetMapping("/project/finance/export") public void exportProjectFinance( @RequestParam(required = false) String status, - @RequestParam(required = false) Long customerId, - @RequestHeader(value = "X-Tenant-Id", required = false) Long tenantId, + @RequestParam(required = false) String customerId, + @RequestHeader(value = "X-Tenant-Id", required = false) String tenantId, HttpServletResponse response) { List data = reportService.getProjectFinance(tenantId, status, customerId); List excelData = convertToExcel(data); diff --git a/fund-report/src/main/java/com/fundplatform/report/dto/ProjectFinanceDTO.java b/fund-report/src/main/java/com/fundplatform/report/dto/ProjectFinanceDTO.java index f478bcb..7336ed0 100644 --- a/fund-report/src/main/java/com/fundplatform/report/dto/ProjectFinanceDTO.java +++ b/fund-report/src/main/java/com/fundplatform/report/dto/ProjectFinanceDTO.java @@ -8,7 +8,7 @@ import java.math.BigDecimal; public class ProjectFinanceDTO { /** 项目ID */ - private Long projectId; + private String projectId; /** 项目编号 */ private String projectCode; @@ -43,11 +43,11 @@ public class ProjectFinanceDTO { /** 利润率 */ private BigDecimal profitRate; - public Long getProjectId() { + public String getProjectId() { return projectId; } - public void setProjectId(Long projectId) { + public void setProjectId(String projectId) { this.projectId = projectId; } diff --git a/fund-report/src/main/java/com/fundplatform/report/feign/ProjectFeignClient.java b/fund-report/src/main/java/com/fundplatform/report/feign/ProjectFeignClient.java index 134593b..2ff38ab 100644 --- a/fund-report/src/main/java/com/fundplatform/report/feign/ProjectFeignClient.java +++ b/fund-report/src/main/java/com/fundplatform/report/feign/ProjectFeignClient.java @@ -26,7 +26,7 @@ public interface ProjectFeignClient { */ @GetMapping("/api/v1/proj/project/stats/finance") Result>> getProjectsWithFinance( - @RequestHeader(value = "X-Tenant-Id", required = false) Long tenantId, + @RequestHeader(value = "X-Tenant-Id", required = false) String tenantId, @RequestParam(required = false) String status, - @RequestParam(required = false) Long customerId); + @RequestParam(required = false) String customerId); } diff --git a/fund-report/src/main/java/com/fundplatform/report/service/ReportService.java b/fund-report/src/main/java/com/fundplatform/report/service/ReportService.java index 70683fb..d0a85bf 100644 --- a/fund-report/src/main/java/com/fundplatform/report/service/ReportService.java +++ b/fund-report/src/main/java/com/fundplatform/report/service/ReportService.java @@ -36,5 +36,5 @@ public interface ReportService { /** * 获取项目收支分析报表 */ - List getProjectFinance(Long tenantId, String status, Long customerId); + List getProjectFinance(String tenantId, String status, String customerId); } diff --git a/fund-report/src/main/java/com/fundplatform/report/service/impl/ReportServiceImpl.java b/fund-report/src/main/java/com/fundplatform/report/service/impl/ReportServiceImpl.java index 9bc9718..67a29a3 100644 --- a/fund-report/src/main/java/com/fundplatform/report/service/impl/ReportServiceImpl.java +++ b/fund-report/src/main/java/com/fundplatform/report/service/impl/ReportServiceImpl.java @@ -211,7 +211,7 @@ public class ReportServiceImpl implements ReportService { } @Override - public List getProjectFinance(Long tenantId, String status, Long customerId) { + public List getProjectFinance(String tenantId, String status, String customerId) { List result = new ArrayList<>(); try { @@ -220,7 +220,7 @@ public class ReportServiceImpl implements ReportService { if (projectsResult != null && projectsResult.getData() != null) { for (Map item : projectsResult.getData()) { ProjectFinanceDTO dto = new ProjectFinanceDTO(); - dto.setProjectId(((Number) item.get("projectId")).longValue()); + dto.setProjectId(String.valueOf(item.get("projectId"))); dto.setProjectCode((String) item.get("projectCode")); dto.setProjectName((String) item.get("projectName")); dto.setCustomerName((String) item.get("customerName")); @@ -262,15 +262,15 @@ public class ReportServiceImpl implements ReportService { } catch (Exception e) { log.warn("获取项目收支分析失败: {}", e.getMessage()); // 返回模拟数据 - result.add(createMockProjectFinance(1L, "PRJ-001", "项目A", "客户A", "progress")); - result.add(createMockProjectFinance(2L, "PRJ-002", "项目B", "客户B", "completed")); - result.add(createMockProjectFinance(3L, "PRJ-003", "项目C", "客户C", "progress")); + result.add(createMockProjectFinance("1", "PRJ-001", "项目A", "客户A", "progress")); + result.add(createMockProjectFinance("2", "PRJ-002", "项目B", "客户B", "completed")); + result.add(createMockProjectFinance("3", "PRJ-003", "项目C", "客户C", "progress")); } return result; } - private ProjectFinanceDTO createMockProjectFinance(Long id, String code, String name, String customer, String status) { + private ProjectFinanceDTO createMockProjectFinance(String id, String code, String name, String customer, String status) { ProjectFinanceDTO dto = new ProjectFinanceDTO(); dto.setProjectId(id); dto.setProjectCode(code); diff --git a/fund-sys/src/main/java/com/fundplatform/sys/controller/OperationLogController.java b/fund-sys/src/main/java/com/fundplatform/sys/controller/OperationLogController.java index 4a6e413..ddd73f0 100644 --- a/fund-sys/src/main/java/com/fundplatform/sys/controller/OperationLogController.java +++ b/fund-sys/src/main/java/com/fundplatform/sys/controller/OperationLogController.java @@ -31,7 +31,7 @@ public class OperationLogController { public Result> page( @Parameter(description = "页码") @RequestParam(defaultValue = "1") int pageNum, @Parameter(description = "每页条数") @RequestParam(defaultValue = "10") int pageSize, - @Parameter(description = "用户ID") @RequestParam(required = false) Long userId, + @Parameter(description = "用户ID") @RequestParam(required = false) String userId, @Parameter(description = "操作类型") @RequestParam(required = false) String operation, @Parameter(description = "开始时间(yyyy-MM-dd HH:mm:ss)") @RequestParam(required = false) String startTime, @Parameter(description = "结束时间(yyyy-MM-dd HH:mm:ss)") @RequestParam(required = false) String endTime) { diff --git a/fund-sys/src/main/java/com/fundplatform/sys/data/entity/SysTenant.java b/fund-sys/src/main/java/com/fundplatform/sys/data/entity/SysTenant.java index 72bf41e..242566e 100644 --- a/fund-sys/src/main/java/com/fundplatform/sys/data/entity/SysTenant.java +++ b/fund-sys/src/main/java/com/fundplatform/sys/data/entity/SysTenant.java @@ -12,9 +12,9 @@ import java.time.LocalDateTime; @TableName("sys_tenant") public class SysTenant extends BaseEntity { - /** 租户表不需要tenant_id字段 */ + /** 租户表不需要tenant_id字段,但需要覆盖父类的getter方法以避免返回null */ @TableField(exist = false) - private String tenantId; + private String tenantId = "master"; public String getTenantId() { return tenantId; diff --git a/fund-sys/src/main/java/com/fundplatform/sys/service/OperationLogService.java b/fund-sys/src/main/java/com/fundplatform/sys/service/OperationLogService.java index f6d3720..411139d 100644 --- a/fund-sys/src/main/java/com/fundplatform/sys/service/OperationLogService.java +++ b/fund-sys/src/main/java/com/fundplatform/sys/service/OperationLogService.java @@ -16,7 +16,7 @@ public interface OperationLogService { /** * 分页查询操作日志 */ - Page pageLogs(int pageNum, int pageSize, Long userId, String operation, String startTime, String endTime); + Page pageLogs(int pageNum, int pageSize, String userId, String operation, String startTime, String endTime); /** * 根据ID查询日志详情 diff --git a/fund-sys/src/main/java/com/fundplatform/sys/service/impl/OperationLogServiceImpl.java b/fund-sys/src/main/java/com/fundplatform/sys/service/impl/OperationLogServiceImpl.java index afc50b4..3c1ca61 100644 --- a/fund-sys/src/main/java/com/fundplatform/sys/service/impl/OperationLogServiceImpl.java +++ b/fund-sys/src/main/java/com/fundplatform/sys/service/impl/OperationLogServiceImpl.java @@ -34,7 +34,7 @@ public class OperationLogServiceImpl implements OperationLogService { } @Override - public Page pageLogs(int pageNum, int pageSize, Long userId, String operation, String startTime, String endTime) { + public Page pageLogs(int pageNum, int pageSize, String userId, String operation, String startTime, String endTime) { Page page = new Page<>(pageNum, pageSize); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); diff --git a/scripts/dev-start.sh b/scripts/dev-start.sh new file mode 100755 index 0000000..d896901 --- /dev/null +++ b/scripts/dev-start.sh @@ -0,0 +1,323 @@ +#!/bin/bash +# ============================================ +# 本地开发环境启动脚本 +# 用法: ./dev-start.sh [选项] +# 选项: +# all - 启动所有服务(默认) +# core - 启动核心服务(gateway + sys + frontend) +# gateway - 仅启动网关 +# sys - 仅启动系统服务 +# cust - 仅启动客户服务 +# proj - 仅启动项目服务 +# req - 仅启动需求服务 +# exp - 仅启动支出服务 +# receipt - 仅启动票据服务 +# file - 仅启动文件服务 +# report - 仅启动报表服务 +# frontend - 仅启动前端 +# help - 显示帮助信息 +# ============================================ + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +APP_HOME="$(dirname "$SCRIPT_DIR")" +LOG_DIR="${APP_HOME}/logs" + +# 创建日志目录 +mkdir -p "${LOG_DIR}" + +# 服务端口配置 +GATEWAY_PORT=8000 +SYS_PORT=8100 +CUST_PORT=8110 +PROJ_PORT=8120 +REQ_PORT=8130 +EXP_PORT=8140 +RECEIPT_PORT=8150 +FILE_PORT=8600 +REPORT_PORT=8700 +FRONTEND_PORT=3000 + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# 检查端口是否被占用 +check_port() { + local port=$1 + if netstat -tlnp 2>/dev/null | grep -q ":${port} "; then + return 0 # 端口被占用 + fi + return 1 # 端口空闲 +} + +# 通用服务启动函数 +# 参数: $1=服务名, $2=模块名, $3=端口, $4=主类名 +start_service() { + local name=$1 + local module=$2 + local port=$3 + local main_class=$4 + + log_info "启动 ${name} 服务 (端口: ${port})..." + + if check_port ${port}; then + log_warn "端口 ${port} 已被占用,跳过 ${name} 启动" + return 0 + fi + + cd "${APP_HOME}" + nohup mvn -pl ${module} exec:java \ + -Dexec.mainClass="${main_class}" \ + > "${LOG_DIR}/${name}-console.log" 2>&1 & + + local pid=$! + echo ${pid} > "${LOG_DIR}/${name}.pid" + log_info "${name} 启动中... PID: ${pid}" + + # 等待启动完成 + sleep 3 + if check_port ${port}; then + log_info "${name} 启动成功!" + else + log_warn "${name} 可能还在启动中,请检查日志: ${LOG_DIR}/${name}-console.log" + fi +} + +# 启动网关服务 +start_gateway() { + start_service "gateway" "fund-gateway" ${GATEWAY_PORT} "com.fundplatform.gateway.GatewayApplication" +} + +# 启动系统服务 +start_sys() { + start_service "sys" "fund-sys" ${SYS_PORT} "com.fundplatform.sys.SysApplication" +} + +# 启动客户服务 +start_cust() { + start_service "cust" "fund-cust" ${CUST_PORT} "com.fundplatform.cust.CustApplication" +} + +# 启动项目服务 +start_proj() { + start_service "proj" "fund-proj" ${PROJ_PORT} "com.fundplatform.proj.ProjApplication" +} + +# 启动需求服务 +start_req() { + start_service "req" "fund-req" ${REQ_PORT} "com.fundplatform.req.ReqApplication" +} + +# 启动支出服务 +start_exp() { + start_service "exp" "fund-exp" ${EXP_PORT} "com.fundplatform.exp.ExpApplication" +} + +# 启动票据服务 +start_receipt() { + start_service "receipt" "fund-receipt" ${RECEIPT_PORT} "com.fundplatform.receipt.ReceiptApplication" +} + +# 启动文件服务 +start_file() { + start_service "file" "fund-file" ${FILE_PORT} "com.fundplatform.file.FileApplication" +} + +# 启动报表服务 +start_report() { + start_service "report" "fund-report" ${REPORT_PORT} "com.fundplatform.report.ReportApplication" +} + +# 启动前端服务 +start_frontend() { + log_info "启动管理后台前端 (端口: ${FRONTEND_PORT})..." + + cd "${APP_HOME}/fund-admin" + + # 检查 node_modules 是否存在 + if [ ! -d "node_modules" ]; then + log_info "安装前端依赖..." + npm install + fi + + # 查找可用端口 + local port=${FRONTEND_PORT} + while check_port ${port}; do + port=$((port + 1)) + if [ ${port} -gt 3010 ]; then + log_error "无法找到可用端口 (3000-3010)" + return 1 + fi + done + + if [ ${port} -ne ${FRONTEND_PORT} ]; then + log_warn "端口 ${FRONTEND_PORT} 已被占用,使用端口 ${port}" + fi + + nohup npm run dev -- --port ${port} --host 0.0.0.0 \ + > "${LOG_DIR}/frontend-console.log" 2>&1 & + + local pid=$! + echo ${pid} > "${LOG_DIR}/frontend.pid" + log_info "前端启动中... PID: ${pid}" + + sleep 3 + log_info "前端启动成功!访问地址: http://localhost:${port}" +} + +# 启动核心服务 +start_core() { + log_info "==========================================" + log_info "启动核心服务..." + log_info "==========================================" + + start_gateway + start_sys + start_frontend + + log_info "==========================================" + log_info "核心服务启动完成!" + log_info "==========================================" +} + +# 启动所有服务 +start_all() { + log_info "==========================================" + log_info "启动本地开发环境(全部服务)..." + log_info "==========================================" + + # 检查 Nacos + if ! check_port 8848; then + log_warn "Nacos (端口8848) 未运行,部分服务可能启动失败" + log_warn "请先启动 Nacos 服务" + fi + + # 检查 MySQL + if ! check_port 3306; then + log_warn "MySQL (端口3306) 未运行,数据库相关服务将启动失败" + log_warn "请先启动 MySQL 服务" + fi + + start_gateway + start_sys + start_cust + start_proj + start_req + start_exp + start_receipt + start_file + start_report + start_frontend + + log_info "==========================================" + log_info "本地开发环境启动完成!" + log_info "==========================================" + echo "" + echo "服务地址:" + echo " 网关: http://localhost:${GATEWAY_PORT}" + echo " 系统: http://localhost:${SYS_PORT}" + echo " 客户: http://localhost:${CUST_PORT}" + echo " 项目: http://localhost:${PROJ_PORT}" + echo " 需求: http://localhost:${REQ_PORT}" + echo " 支出: http://localhost:${EXP_PORT}" + echo " 票据: http://localhost:${RECEIPT_PORT}" + echo " 文件: http://localhost:${FILE_PORT}" + echo " 报表: http://localhost:${REPORT_PORT}" + echo " 前端: http://localhost:${FRONTEND_PORT} (或查看日志获取实际端口)" + echo "" + echo "日志目录: ${LOG_DIR}" + echo "停止服务: ./scripts/dev-stop.sh" +} + +# 显示帮助 +show_help() { + echo "用法: $0 [选项]" + echo "" + echo "选项:" + echo " all 启动所有服务(默认)" + echo " core 启动核心服务(gateway + sys + frontend)" + echo " gateway 仅启动网关服务" + echo " sys 仅启动系统服务" + echo " cust 仅启动客户服务" + echo " proj 仅启动项目服务" + echo " req 仅启动需求服务" + echo " exp 仅启动支出服务" + echo " receipt 仅启动票据服务" + echo " file 仅启动文件服务" + echo " report 仅启动报表服务" + echo " frontend 仅启动前端服务" + echo " help 显示此帮助信息" + echo "" + echo "服务端口:" + echo " gateway: ${GATEWAY_PORT} | sys: ${SYS_PORT} | cust: ${CUST_PORT}" + echo " proj: ${PROJ_PORT} | req: ${REQ_PORT} | exp: ${EXP_PORT}" + echo " receipt: ${RECEIPT_PORT} | file: ${FILE_PORT} | report: ${REPORT_PORT}" + echo "" + echo "示例:" + echo " $0 # 启动所有服务" + echo " $0 core # 启动核心服务(网关+系统+前端)" + echo " $0 sys cust # 启动系统和客户服务" + echo " $0 frontend # 仅启动前端" +} + +# 主入口 +case "$1" in + gateway) + start_gateway + ;; + sys) + start_sys + ;; + cust) + start_cust + ;; + proj) + start_proj + ;; + req) + start_req + ;; + exp) + start_exp + ;; + receipt) + start_receipt + ;; + file) + start_file + ;; + report) + start_report + ;; + frontend) + start_frontend + ;; + core) + start_core + ;; + help|--help|-h) + show_help + ;; + all|"") + start_all + ;; + *) + log_error "未知选项: $1" + show_help + exit 1 + ;; +esac diff --git a/scripts/dev-status.sh b/scripts/dev-status.sh new file mode 100755 index 0000000..71305d1 --- /dev/null +++ b/scripts/dev-status.sh @@ -0,0 +1,138 @@ +#!/bin/bash +# ============================================ +# 本地开发环境状态检查脚本 +# 用法: ./dev-status.sh +# ============================================ + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 服务端口配置 +GATEWAY_PORT=8000 +SYS_PORT=8100 +CUST_PORT=8110 +PROJ_PORT=8120 +REQ_PORT=8130 +EXP_PORT=8140 +RECEIPT_PORT=8150 +FILE_PORT=8600 +REPORT_PORT=8700 + +# 检查端口状态 +check_port_status() { + local port=$1 + local service=$2 + local pid="" + + if netstat -tlnp 2>/dev/null | grep -q ":${port} "; then + pid=$(netstat -tlnp 2>/dev/null | grep ":${port} " | awk '{print $7}' | cut -d'/' -f1) + echo -e " ${GREEN}✓${NC} ${service} (端口 ${port}, PID: ${pid})" + return 0 + else + echo -e " ${RED}✗${NC} ${service} (端口 ${port})" + return 1 + fi +} + +# 检查前端状态 +check_frontend_status() { + local vite_pids=$(pgrep -f "vite.*fund-admin" | head -1) + + if [ -n "${vite_pids}" ]; then + local port=$(netstat -tlnp 2>/dev/null | grep "${vite_pids}/node" | awk '{print $4}' | grep -oP ':\d+$' | tr -d ':') + echo -e " ${GREEN}✓${NC} 前端 (fund-admin) - 端口: ${port:-未知}, PID: ${vite_pids}" + echo -e " 访问地址: http://localhost:${port:-3000}" + else + echo -e " ${RED}✗${NC} 前端 (fund-admin)" + fi +} + +# 检查依赖服务 +check_dependencies() { + echo "" + echo -e "${BLUE}依赖服务:${NC}" + + # Nacos + if netstat -tlnp 2>/dev/null | grep -q ":8848 "; then + echo -e " ${GREEN}✓${NC} Nacos (8848)" + else + echo -e " ${RED}✗${NC} Nacos (8848) - 未运行" + fi + + # MySQL + if netstat -tlnp 2>/dev/null | grep -q ":3306 "; then + echo -e " ${GREEN}✓${NC} MySQL (3306)" + else + echo -e " ${RED}✗${NC} MySQL (3306) - 未运行" + fi + + # Redis + if netstat -tlnp 2>/dev/null | grep -q ":6379 "; then + echo -e " ${GREEN}✓${NC} Redis (6379)" + else + echo -e " ${YELLOW}?${NC} Redis (6379) - 未运行 (可选)" + fi +} + +# 统计运行中的服务数量 +count_running_services() { + local count=0 + for port in ${GATEWAY_PORT} ${SYS_PORT} ${CUST_PORT} ${PROJ_PORT} ${REQ_PORT} ${EXP_PORT} ${RECEIPT_PORT} ${FILE_PORT} ${REPORT_PORT}; do + if netstat -tlnp 2>/dev/null | grep -q ":${port} "; then + ((count++)) + fi + done + echo ${count} +} + +# 主函数 +main() { + echo "" + echo -e "${BLUE}==========================================${NC}" + echo -e "${BLUE} 本地开发环境状态${NC}" + echo -e "${BLUE}==========================================${NC}" + echo "" + + echo -e "${BLUE}后端服务:${NC}" + check_port_status ${GATEWAY_PORT} "网关 (fund-gateway)" + check_port_status ${SYS_PORT} "系统 (fund-sys)" + check_port_status ${CUST_PORT} "客户 (fund-cust)" + check_port_status ${PROJ_PORT} "项目 (fund-proj)" + check_port_status ${REQ_PORT} "需求 (fund-req)" + check_port_status ${EXP_PORT} "支出 (fund-exp)" + check_port_status ${RECEIPT_PORT} "票据 (fund-receipt)" + check_port_status ${FILE_PORT} "文件 (fund-file)" + check_port_status ${REPORT_PORT} "报表 (fund-report)" + + echo "" + echo -e "${BLUE}前端服务:${NC}" + check_frontend_status + + local running=$(count_running_services) + echo "" + echo -e "已启动 ${GREEN}${running}${NC}/9 个后端服务" + + check_dependencies + + echo "" + echo -e "${BLUE}==========================================${NC}" + echo -e "操作命令:" + echo -e " 启动所有: ${GREEN}./scripts/dev-start.sh${NC}" + echo -e " 启动核心: ${GREEN}./scripts/dev-start.sh core${NC}" + echo -e " 停止所有: ${GREEN}./scripts/dev-stop.sh${NC}" + echo -e " 查看状态: ${GREEN}./scripts/dev-status.sh${NC}" + echo "" + echo -e "单独启动服务:" + echo -e " ${GREEN}./scripts/dev-start.sh sys${NC} # 系统服务" + echo -e " ${GREEN}./scripts/dev-start.sh cust${NC} # 客户服务" + echo -e " ${GREEN}./scripts/dev-start.sh proj${NC} # 项目服务" + echo -e " ${GREEN}./scripts/dev-start.sh frontend${NC} # 前端服务" + echo -e "${BLUE}==========================================${NC}" + echo "" +} + +main diff --git a/scripts/dev-stop.sh b/scripts/dev-stop.sh new file mode 100755 index 0000000..58395d5 --- /dev/null +++ b/scripts/dev-stop.sh @@ -0,0 +1,237 @@ +#!/bin/bash +# ============================================ +# 本地开发环境停止脚本 +# 用法: ./dev-stop.sh [选项] +# 选项: +# all - 停止所有服务(默认) +# gateway - 仅停止网关 +# sys - 仅停止系统服务 +# cust - 仅停止客户服务 +# proj - 仅停止项目服务 +# req - 仅停止需求服务 +# exp - 仅停止支出服务 +# receipt - 仅停止票据服务 +# file - 仅停止文件服务 +# report - 仅停止报表服务 +# frontend - 仅停止前端 +# help - 显示帮助信息 +# ============================================ + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +APP_HOME="$(dirname "$SCRIPT_DIR")" +LOG_DIR="${APP_HOME}/logs" + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +# 停止服务 +# 参数: $1=服务名, $2=进程匹配模式 +stop_service() { + local name=$1 + local pattern=$2 + local pid_file="${LOG_DIR}/${name}.pid" + + if [ -f "${pid_file}" ]; then + local pid=$(cat "${pid_file}") + if ps -p ${pid} > /dev/null 2>&1; then + log_info "停止 ${name} 服务 (PID: ${pid})..." + kill ${pid} 2>/dev/null + + # 等待进程结束 + local count=0 + while ps -p ${pid} > /dev/null 2>&1; do + if [ $count -ge 10 ]; then + log_warn "${name} 未响应,强制终止..." + kill -9 ${pid} 2>/dev/null + break + fi + sleep 1 + ((count++)) + done + + log_info "${name} 服务已停止" + else + log_warn "${name} 服务未运行" + fi + rm -f "${pid_file}" + else + # 通过进程名查找 + local pids=$(pgrep -f "${pattern}") + if [ -n "${pids}" ]; then + log_info "停止 ${name} 服务 (PIDs: ${pids})..." + echo "${pids}" | xargs kill 2>/dev/null + log_info "${name} 服务已停止" + else + log_warn "${name} 服务未运行" + fi + fi +} + +# 停止网关 +stop_gateway() { + stop_service "gateway" "fund-gateway.*GatewayApplication" +} + +# 停止系统服务 +stop_sys() { + stop_service "sys" "fund-sys.*SysApplication" +} + +# 停止客户服务 +stop_cust() { + stop_service "cust" "fund-cust.*CustApplication" +} + +# 停止项目服务 +stop_proj() { + stop_service "proj" "fund-proj.*ProjApplication" +} + +# 停止需求服务 +stop_req() { + stop_service "req" "fund-req.*ReqApplication" +} + +# 停止支出服务 +stop_exp() { + stop_service "exp" "fund-exp.*ExpApplication" +} + +# 停止票据服务 +stop_receipt() { + stop_service "receipt" "fund-receipt.*ReceiptApplication" +} + +# 停止文件服务 +stop_file() { + stop_service "file" "fund-file.*FileApplication" +} + +# 停止报表服务 +stop_report() { + stop_service "report" "fund-report.*ReportApplication" +} + +# 停止前端 +stop_frontend() { + log_info "停止前端服务..." + + # 停止 vite 进程 + local vite_pids=$(pgrep -f "vite.*fund-admin") + if [ -n "${vite_pids}" ]; then + log_info "停止前端服务 (PIDs: ${vite_pids})..." + echo "${vite_pids}" | xargs kill 2>/dev/null + log_info "前端服务已停止" + else + log_warn "前端服务未运行" + fi + + # 清理 PID 文件 + rm -f "${LOG_DIR}/frontend.pid" +} + +# 停止所有服务 +stop_all() { + log_info "==========================================" + log_info "停止本地开发环境..." + log_info "==========================================" + + stop_frontend + stop_gateway + stop_sys + stop_cust + stop_proj + stop_req + stop_exp + stop_receipt + stop_file + stop_report + + log_info "==========================================" + log_info "本地开发环境已停止" + log_info "==========================================" +} + +# 显示帮助 +show_help() { + echo "用法: $0 [选项]" + echo "" + echo "选项:" + echo " all 停止所有服务(默认)" + echo " gateway 仅停止网关服务" + echo " sys 仅停止系统服务" + echo " cust 仅停止客户服务" + echo " proj 仅停止项目服务" + echo " req 仅停止需求服务" + echo " exp 仅停止支出服务" + echo " receipt 仅停止票据服务" + echo " file 仅停止文件服务" + echo " report 仅停止报表服务" + echo " frontend 仅停止前端服务" + echo " help 显示此帮助信息" + echo "" + echo "示例:" + echo " $0 # 停止所有服务" + echo " $0 sys # 仅停止系统服务" + echo " $0 frontend # 仅停止前端" +} + +# 主入口 +case "$1" in + gateway) + stop_gateway + ;; + sys) + stop_sys + ;; + cust) + stop_cust + ;; + proj) + stop_proj + ;; + req) + stop_req + ;; + exp) + stop_exp + ;; + receipt) + stop_receipt + ;; + file) + stop_file + ;; + report) + stop_report + ;; + frontend) + stop_frontend + ;; + help|--help|-h) + show_help + ;; + all|"") + stop_all + ;; + *) + log_error "未知选项: $1" + show_help + exit 1 + ;; +esac