feat: 新增本地开发启动脚本及各模块代码优化
- 新增 scripts/dev-start.sh: 本地开发环境启动脚本,支持启动所有/核心/单个服务 - 新增 scripts/dev-stop.sh: 本地开发环境停止脚本 - 新增 scripts/dev-status.sh: 服务状态检查脚本 - 优化各模块 Controller/Service/VO/DTO 代码 - 删除过时的计划文件
This commit is contained in:
parent
9a55286869
commit
cc6577b3df
@ -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接口必须鉴权,敏感数据加密
|
||||
@ -28,7 +28,7 @@ public class ExpenseTypeController {
|
||||
* 创建支出类型
|
||||
*/
|
||||
@PostMapping
|
||||
public Result<Long> create(@Valid @RequestBody ExpenseTypeDTO dto) {
|
||||
public Result<String> create(@Valid @RequestBody ExpenseTypeDTO dto) {
|
||||
return Result.success(typeService.createType(dto));
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ public class ExpenseTypeController {
|
||||
* 更新支出类型
|
||||
*/
|
||||
@PutMapping("/{id}")
|
||||
public Result<Boolean> update(@PathVariable Long id, @Valid @RequestBody ExpenseTypeDTO dto) {
|
||||
public Result<Boolean> 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<ExpenseTypeVO> getById(@PathVariable Long id) {
|
||||
public Result<ExpenseTypeVO> getById(@PathVariable String id) {
|
||||
return Result.success(typeService.getTypeById(id));
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ public class ExpenseTypeController {
|
||||
* 查询指定父级的子类型列表
|
||||
*/
|
||||
@GetMapping("/children")
|
||||
public Result<List<ExpenseTypeVO>> getChildren(@RequestParam(required = false) Long parentId) {
|
||||
public Result<List<ExpenseTypeVO>> getChildren(@RequestParam(required = false) String parentId) {
|
||||
return Result.success(typeService.getChildrenByParentId(parentId));
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ public class ExpenseTypeController {
|
||||
* 删除支出类型
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
public Result<Boolean> delete(@PathVariable Long id) {
|
||||
public Result<Boolean> delete(@PathVariable String id) {
|
||||
return Result.success(typeService.deleteType(id));
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ public class ExpenseTypeController {
|
||||
* 更新状态
|
||||
*/
|
||||
@PutMapping("/{id}/status")
|
||||
public Result<Boolean> updateStatus(@PathVariable Long id, @RequestParam Integer status) {
|
||||
public Result<Boolean> updateStatus(@PathVariable String id, @RequestParam Integer status) {
|
||||
return Result.success(typeService.updateStatus(id, status));
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ public class FundExpenseController {
|
||||
* 创建支出申请
|
||||
*/
|
||||
@PostMapping
|
||||
public Result<Long> create(@Valid @RequestBody FundExpenseDTO dto) {
|
||||
public Result<String> create(@Valid @RequestBody FundExpenseDTO dto) {
|
||||
return Result.success(expenseService.createExpense(dto));
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ public class FundExpenseController {
|
||||
* 更新支出申请(仅待审批状态可修改)
|
||||
*/
|
||||
@PutMapping("/{id}")
|
||||
public Result<Boolean> update(@PathVariable Long id, @Valid @RequestBody FundExpenseDTO dto) {
|
||||
public Result<Boolean> 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<FundExpenseVO> getById(@PathVariable Long id) {
|
||||
public Result<FundExpenseVO> 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<FundExpenseVO> page = expenseService.pageExpenses(pageNum, pageSize, title, expenseType, payStatus, approvalStatus);
|
||||
@ -84,7 +84,7 @@ public class FundExpenseController {
|
||||
* 删除支出申请(仅待审批状态可删除)
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
public Result<Boolean> delete(@PathVariable Long id) {
|
||||
public Result<Boolean> delete(@PathVariable String id) {
|
||||
return Result.success(expenseService.deleteExpense(id));
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ public class FundExpenseController {
|
||||
* 提交审批(待审批 -> 审批中)
|
||||
*/
|
||||
@PostMapping("/{id}/submit")
|
||||
public Result<Boolean> submitApproval(@PathVariable Long id) {
|
||||
public Result<Boolean> submitApproval(@PathVariable String id) {
|
||||
return Result.success(expenseService.submitApproval(id));
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ public class FundExpenseController {
|
||||
* 撤回审批(审批中 -> 待审批)
|
||||
*/
|
||||
@PostMapping("/{id}/withdraw")
|
||||
public Result<Boolean> withdrawApproval(@PathVariable Long id) {
|
||||
public Result<Boolean> withdrawApproval(@PathVariable String id) {
|
||||
return Result.success(expenseService.withdrawApproval(id));
|
||||
}
|
||||
|
||||
@ -109,9 +109,9 @@ public class FundExpenseController {
|
||||
*/
|
||||
@PutMapping("/{id}/approve")
|
||||
public Result<Boolean> 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<Boolean> 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<Boolean> 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<Boolean> payFailed(@PathVariable Long id, @RequestParam String reason) {
|
||||
public Result<Boolean> 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) {
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -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<FundExpenseVO> pageExpenses(int pageNum, int pageSize, String title, Long expenseType, Integer payStatus, Integer approvalStatus);
|
||||
Page<FundExpenseVO> pageExpenses(int pageNum, int pageSize, String title, String expenseType, Integer payStatus, Integer approvalStatus);
|
||||
|
||||
/**
|
||||
* 查询支出列表(不分页,用于导出)
|
||||
*/
|
||||
java.util.List<FundExpenseVO> listExpenses(String title, Long expenseType, Integer payStatus, Integer approvalStatus);
|
||||
java.util.List<FundExpenseVO> 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);
|
||||
|
||||
// ===================== 统计相关 =====================
|
||||
|
||||
|
||||
@ -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<FundExpenseVO> pageExpenses(int pageNum, int pageSize, String title, Long expenseType, Integer payStatus, Integer approvalStatus) {
|
||||
public Page<FundExpenseVO> pageExpenses(int pageNum, int pageSize, String title, String expenseType, Integer payStatus, Integer approvalStatus) {
|
||||
Page<FundExpense> page = new Page<>(pageNum, pageSize);
|
||||
LambdaQueryWrapper<FundExpense> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(FundExpense::getDeleted, 0);
|
||||
@ -136,7 +136,7 @@ public class FundExpenseServiceImpl implements FundExpenseService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FundExpenseVO> listExpenses(String title, Long expenseType, Integer payStatus, Integer approvalStatus) {
|
||||
public List<FundExpenseVO> listExpenses(String title, String expenseType, Integer payStatus, Integer approvalStatus) {
|
||||
LambdaQueryWrapper<FundExpense> 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<FundExpense> expenses = expenseDataService.list(wrapper);
|
||||
|
||||
Map<Long, BigDecimal> typeAmountMap = new HashMap<>();
|
||||
Map<Long, Integer> typeCountMap = new HashMap<>();
|
||||
Map<String, BigDecimal> typeAmountMap = new HashMap<>();
|
||||
Map<String, Integer> 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<Map<String, Object>> result = new ArrayList<>();
|
||||
for (Long type : typeAmountMap.keySet()) {
|
||||
for (String type : typeAmountMap.keySet()) {
|
||||
Map<String, Object> item = new HashMap<>();
|
||||
item.put("type", type);
|
||||
item.put("name", getExpenseTypeName(type));
|
||||
|
||||
@ -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; }
|
||||
}
|
||||
|
||||
@ -55,10 +55,10 @@ public class FileController {
|
||||
public Result<FileRecordVO> 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<FileRecordVO> getById(@PathVariable Long id) {
|
||||
public Result<FileRecordVO> 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<FileRecord> page = fileRecordService.page(pageNum, pageSize, businessType, businessId, fileType);
|
||||
@ -231,7 +231,7 @@ public class FileController {
|
||||
@GetMapping("/list")
|
||||
public Result<List<FileRecordVO>> listByBusiness(
|
||||
@RequestParam String businessType,
|
||||
@RequestParam Long businessId) {
|
||||
@RequestParam String businessId) {
|
||||
|
||||
List<FileRecord> records = fileRecordService.listByBusiness(businessType, businessId);
|
||||
List<FileRecordVO> voList = new ArrayList<>();
|
||||
@ -245,7 +245,7 @@ public class FileController {
|
||||
* 删除文件
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
public Result<Boolean> delete(@PathVariable Long id) {
|
||||
public Result<Boolean> delete(@PathVariable String id) {
|
||||
FileRecord record = fileRecordService.getById(id);
|
||||
if (record == null) {
|
||||
return Result.error("文件不存在");
|
||||
|
||||
@ -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<FileRecord> page(int pageNum, int pageSize, String businessType, Long businessId, String fileType) {
|
||||
public Page<FileRecord> page(int pageNum, int pageSize, String businessType, String businessId, String fileType) {
|
||||
Page<FileRecord> page = new Page<>(pageNum, pageSize);
|
||||
LambdaQueryWrapper<FileRecord> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(businessType != null, FileRecord::getBusinessType, businessType);
|
||||
@ -59,7 +59,7 @@ public class FileRecordService {
|
||||
/**
|
||||
* 根据业务类型和ID查询
|
||||
*/
|
||||
public List<FileRecord> listByBusiness(String businessType, Long businessId) {
|
||||
public List<FileRecord> listByBusiness(String businessType, String businessId) {
|
||||
LambdaQueryWrapper<FileRecord> 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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ public class RequirementController {
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public Result<Page<RequirementVO>> 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<RequirementVO> get(
|
||||
@RequestHeader("X-Tenant-Id") Long tenantId,
|
||||
@PathVariable Long requirementId) {
|
||||
@RequestHeader("X-Tenant-Id") String tenantId,
|
||||
@PathVariable String requirementId) {
|
||||
return requirementService.getById(tenantId, requirementId);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -47,8 +47,8 @@ public class RequirementService {
|
||||
/**
|
||||
* 分页查询需求工单
|
||||
*/
|
||||
public Result<Page<RequirementVO>> page(Long tenantId, String requirementName, String status,
|
||||
Long projectId, Long customerId, int current, int size) {
|
||||
public Result<Page<RequirementVO>> page(String tenantId, String requirementName, String status,
|
||||
String projectId, String customerId, int current, int size) {
|
||||
Page<Requirement> page = new Page<>(current, size);
|
||||
LambdaQueryWrapper<Requirement> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Requirement::getTenantId, tenantId);
|
||||
@ -80,7 +80,7 @@ public class RequirementService {
|
||||
/**
|
||||
* 查询需求工单详情
|
||||
*/
|
||||
public Result<RequirementVO> getById(Long tenantId, Long requirementId) {
|
||||
public Result<RequirementVO> getById(String tenantId, String requirementId) {
|
||||
Requirement requirement = requirementDataService.getOne(
|
||||
new LambdaQueryWrapper<Requirement>()
|
||||
.eq(Requirement::getId, requirementId)
|
||||
|
||||
@ -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<FundReceiptVO> pageReceipts(int pageNum, int pageSize, String title, Integer receiptType, Integer receiptStatus);
|
||||
|
||||
/**
|
||||
* 根据应收款ID查询收款记录
|
||||
*/
|
||||
List<FundReceiptVO> getReceiptsByReceivableId(Long receivableId);
|
||||
List<FundReceiptVO> 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);
|
||||
}
|
||||
|
||||
@ -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<ReceivableVO> pageReceivables(int pageNum, int pageSize, Long projectId, Long customerId, String status, Integer confirmStatus);
|
||||
Page<ReceivableVO> pageReceivables(int pageNum, int pageSize, String projectId, String customerId, String status, Integer confirmStatus);
|
||||
|
||||
/**
|
||||
* 查询应收款列表(不分页,用于导出)
|
||||
*/
|
||||
List<ReceivableVO> listReceivables(Long projectId, Long customerId, String status, Integer confirmStatus);
|
||||
List<ReceivableVO> 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<FundReceiptVO> getReceiptsByReceivableId(Long receivableId);
|
||||
List<FundReceiptVO> getReceiptsByReceivableId(String receivableId);
|
||||
|
||||
/**
|
||||
* 更新逾期状态
|
||||
@ -66,7 +66,7 @@ public interface ReceivableService {
|
||||
/**
|
||||
* 删除应收款
|
||||
*/
|
||||
boolean deleteReceivable(Long id);
|
||||
boolean deleteReceivable(String id);
|
||||
|
||||
// ===================== 统计相关 =====================
|
||||
|
||||
|
||||
@ -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<FundReceiptVO> getReceiptsByReceivableId(Long receivableId) {
|
||||
public List<FundReceiptVO> getReceiptsByReceivableId(String receivableId) {
|
||||
LambdaQueryWrapper<FundReceipt> 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<FundReceipt> 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<FundReceipt> 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<FundReceipt> wrapper = new LambdaUpdateWrapper<>();
|
||||
wrapper.eq(FundReceipt::getId, id).set(FundReceipt::getReceiptStatus, 2)
|
||||
.set(FundReceipt::getWriteOffTime, LocalDateTime.now())
|
||||
|
||||
@ -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<ReceivableVO> pageReceivables(int pageNum, int pageSize, Long projectId, Long customerId, String status, Integer confirmStatus) {
|
||||
public Page<ReceivableVO> pageReceivables(int pageNum, int pageSize, String projectId, String customerId, String status, Integer confirmStatus) {
|
||||
Page<Receivable> page = new Page<>(pageNum, pageSize);
|
||||
LambdaQueryWrapper<Receivable> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Receivable::getDeleted, 0);
|
||||
@ -138,7 +138,7 @@ public class ReceivableServiceImpl implements ReceivableService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReceivableVO> listReceivables(Long projectId, Long customerId, String status, Integer confirmStatus) {
|
||||
public List<ReceivableVO> listReceivables(String projectId, String customerId, String status, Integer confirmStatus) {
|
||||
LambdaQueryWrapper<Receivable> 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<FundReceiptVO> getReceiptsByReceivableId(Long receivableId) {
|
||||
public List<FundReceiptVO> 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("应收款不存在");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -66,8 +66,8 @@ public class ReportController {
|
||||
@GetMapping("/project/finance")
|
||||
public Result<List<ProjectFinanceDTO>> 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<ProjectFinanceDTO> data = reportService.getProjectFinance(tenantId, status, customerId);
|
||||
List<ProjectFinanceExcel> excelData = convertToExcel(data);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ public interface ProjectFeignClient {
|
||||
*/
|
||||
@GetMapping("/api/v1/proj/project/stats/finance")
|
||||
Result<List<Map<String, Object>>> 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);
|
||||
}
|
||||
|
||||
@ -36,5 +36,5 @@ public interface ReportService {
|
||||
/**
|
||||
* 获取项目收支分析报表
|
||||
*/
|
||||
List<ProjectFinanceDTO> getProjectFinance(Long tenantId, String status, Long customerId);
|
||||
List<ProjectFinanceDTO> getProjectFinance(String tenantId, String status, String customerId);
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ public class ReportServiceImpl implements ReportService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectFinanceDTO> getProjectFinance(Long tenantId, String status, Long customerId) {
|
||||
public List<ProjectFinanceDTO> getProjectFinance(String tenantId, String status, String customerId) {
|
||||
List<ProjectFinanceDTO> result = new ArrayList<>();
|
||||
|
||||
try {
|
||||
@ -220,7 +220,7 @@ public class ReportServiceImpl implements ReportService {
|
||||
if (projectsResult != null && projectsResult.getData() != null) {
|
||||
for (Map<String, Object> 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);
|
||||
|
||||
@ -31,7 +31,7 @@ public class OperationLogController {
|
||||
public Result<Page<OperationLog>> 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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -16,7 +16,7 @@ public interface OperationLogService {
|
||||
/**
|
||||
* 分页查询操作日志
|
||||
*/
|
||||
Page<OperationLog> pageLogs(int pageNum, int pageSize, Long userId, String operation, String startTime, String endTime);
|
||||
Page<OperationLog> pageLogs(int pageNum, int pageSize, String userId, String operation, String startTime, String endTime);
|
||||
|
||||
/**
|
||||
* 根据ID查询日志详情
|
||||
|
||||
@ -34,7 +34,7 @@ public class OperationLogServiceImpl implements OperationLogService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<OperationLog> pageLogs(int pageNum, int pageSize, Long userId, String operation, String startTime, String endTime) {
|
||||
public Page<OperationLog> pageLogs(int pageNum, int pageSize, String userId, String operation, String startTime, String endTime) {
|
||||
Page<OperationLog> page = new Page<>(pageNum, pageSize);
|
||||
LambdaQueryWrapper<OperationLog> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
|
||||
323
scripts/dev-start.sh
Executable file
323
scripts/dev-start.sh
Executable file
@ -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
|
||||
138
scripts/dev-status.sh
Executable file
138
scripts/dev-status.sh
Executable file
@ -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
|
||||
237
scripts/dev-stop.sh
Executable file
237
scripts/dev-stop.sh
Executable file
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user