智慧水务管理系统 - 精河县供水工程综合管理平台
bot_dev1 bf06818e79 feat: 完整的项目文档 (#96) пре 1 недеља
..
README.md feat: 完整的项目文档 (#96) пре 1 недеља

README.md

开发者指南

开发环境搭建

环境要求

  • JDK 17+
  • Maven 3.6+
  • Node.js 16+
  • MySQL 8.0+
  • Redis 6.0+

1. 项目结构

water-management-system/
├── wm-common/              # 公共模块
│   ├── wm-common-core/     # 核心工具类
│   ├── wm-common-security/  # 安全相关
│   └── wm-common-db/       # 数据库相关
├── wm-revenue/            # 收费管理服务
├── wm-production/         # 生产管理服务
├── wm-dma/                # DMA管理服务
├── wm-data-engine/       # 数据引擎服务
├── wm-mobile-app/         # 移动应用服务
├── config/               # 配置文件
├── scripts/              # 脚本文件
└── docs/                 # 文档文件

2. 快速开始

2.1 克隆项目

git clone http://git.xayunmei.com/bot_ym/water-management-system.git
cd water-management-system

2.2 编译项目

# 编译所有服务
mvn clean compile

# 跳过测试编译
mvn clean compile -DskipTests

2.3 运行单个服务

# 收费管理服务
cd wm-revenue
mvn spring-boot:run

# 生产管理服务
cd wm-production
mvn spring-boot:run

# DMA管理服务
cd wm-dma
mvn spring-boot:run

3. 代码规范

3.1 Java代码规范

  • 使用最新 Java 17 特性
  • 遵循阿里巴巴Java开发规范
  • 使用 Lombok 减少样板代码
  • 统一异常处理机制

3.2 命名规范

  • 包名: 全小写,使用公司域名倒序
  • 类名: 驼峰命名,首字母大写
  • 方法名: 驼峰命名,首字母小写
  • 变量名: 驼峰命名,首字母小写
  • 常量: 全大写,下划线分隔

3.3 提交规范

格式: <类型>(<范围>): <描述>

类型:
- feat: 新功能
- fix: 修复bug
- docs: 文档更新
- style: 代码格式调整
- refactor: 重构
- test: 测试相关
- chore: 构建或辅助工具的变动

示例:
- feat(revenue): 添加在线支付功能
- fix(dma): 修复压力监控数据异常
- docs(api): 更新API文档

4. 数据库开发

4.1 实体定义

@Entity
@Table(name = "users")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long userId;
    
    @Column(unique = true, nullable = false)
    private String username;
    
    @Column(nullable = false)
    private String password;
    
    @Column
    private String realName;
    
    @Email
    @Column
    private String email;
    
    @Pattern(regexp = "^1[3-9]\\d{9}$")
    @Column
    private String phone;
    
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private UserType userType;
    
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private UserStatus status;
    
    @CreationTimestamp
    @Column(nullable = false)
    private LocalDateTime createdAt;
    
    @UpdateTimestamp
    @Column(nullable = false)
    private LocalDateTime updatedAt;
}

4.2 数据访问层

@Mapper
public interface UserMapper extends BaseMapper<User> {
    
    @Select("SELECT * FROM users WHERE username = #{username}")
    User findByUsername(String username);
    
    @Select("SELECT * FROM users WHERE email = #{email}")
    User findByEmail(String email);
}

5. API开发

5.1 控制器定义

@RestController
@RequestMapping("/api/revenue")
@RequiredArgsConstructor
@Slf4j
public class RevenueController {
    
    private final UserService userService;
    private final BillService billService;
    
    @GetMapping("/users")
    public Result<List<UserDTO>> getUsers() {
        List<UserDTO> users = userService.getAllUsers();
        return Result.success(users);
    }
    
    @PostMapping("/bills")
    public Result<BillDTO> createBill(@RequestBody BillCreateRequest request) {
        BillDTO bill = billService.createBill(request);
        return Result.success(bill);
    }
}

5.2 服务层

@Service
@RequiredArgsConstructor
@Slf4j
public class RevenueService {
    
    private final UserRepository userRepository;
    private final BillRepository billRepository;
    
    @Transactional
    public BillDTO createBill(BillCreateRequest request) {
        User user = userRepository.findById(request.getUserId())
            .orElseThrow(() -> new UserNotFoundException("用户不存在"));
        
        Bill bill = Bill.builder()
            .user(user)
            .billNumber(generateBillNumber())
            .billType(request.getBillType())
            .billingPeriod(request.getBillingPeriod())
            .previousReading(request.getPreviousReading())
            .currentReading(request.getCurrentReading())
            .usageAmount(calculateUsageAmount(request.getPreviousReading(), request.getCurrentReading()))
            .unitPrice(request.getUnitPrice())
            .totalAmount(calculateTotalAmount(request.getUsageAmount(), request.getUnitPrice()))
            .dueDate(calculateDueDate(request.getBillingPeriod()))
            .paymentStatus(PaymentStatus.UNPAID)
            .build();
        
        Bill savedBill = billRepository.save(bill);
        return convertToDTO(savedBill);
    }
}

6. 测试开发

6.1 单元测试

@SpringBootTest
@RequiredArgsConstructor
class RevenueServiceTest {
    
    private final RevenueService revenueService;
    
    @Test
    void testCreateBill() {
        BillCreateRequest request = BillCreateRequest.builder()
            .userId(1L)
            .billType(BillType.WATER)
            .billingPeriod(LocalDate.now())
            .previousReading(100.0)
            .currentReading(150.0)
            .unitPrice(3.5)
            .build();
        
        BillDTO result = revenueService.createBill(request);
        
        assertThat(result).isNotNull();
        assertThat(result.getBillNumber()).isNotEmpty();
        assertThat(result.getTotalAmount()).isEqualTo(175.0);
    }
}

7. 部署与运维

7.1 Docker化

# wm-revenue/Dockerfile
FROM openjdk:17-jre-slim

WORKDIR /app

COPY target/wm-revenue-0.0.1-SNAPSHOT.jar app.jar

EXPOSE 8081

ENV JAVA_OPTS="-Xms512m -Xmx1024m"

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

7.2 监控与日志

<!-- logback-spring.xml -->
<configuration>
    <property name="LOG_PATH" value="logs"/>
    
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/wm-revenue.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/wm-revenue.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxFileSize>100MB</maxFileSize>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="FILE"/>
    </root>
</configuration>

自动生成于 2026-06-16