feat: 新增资产管理模块 - 停车场和车型参数管理

- 停车场管理:CRUD + 业务校验 + 权限控制
- 车型参数管理:主子表关联 + 维保项目管理
- 数据库表结构:asset_parking, asset_vehicle_model, asset_vehicle_model_maintain_item
- 优化点:参数校验、业务逻辑校验、类型安全
This commit is contained in:
k kfluous
2026-03-12 03:04:11 +08:00
parent ca98eabf3a
commit a614df46f3
32 changed files with 2004 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
-- =============================================
-- 资产管理系统 - 停车场和车型参数模块
-- 创建时间: 2026-03-12
-- 修正版本:兼容 MySQL 8.0
-- =============================================
-- 1. 创建停车场表(如果不存在)
CREATE TABLE IF NOT EXISTS `asset_parking` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(100) NOT NULL COMMENT '停车场名称',
`principal` varchar(50) DEFAULT NULL COMMENT '公司负责人',
`contact_name` varchar(50) DEFAULT NULL COMMENT '联系人',
`contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`address` varchar(255) DEFAULT NULL COMMENT '地址',
`longitude` varchar(50) DEFAULT NULL COMMENT '经度',
`latitude` varchar(50) DEFAULT NULL COMMENT '纬度',
`stock_area` int DEFAULT NULL COMMENT '库存区域(字典)',
`unusual_action_city` int DEFAULT NULL COMMENT '异动城市(字典)',
`capacity` int DEFAULT 0 COMMENT '容量',
`parked_amount` int DEFAULT 0 COMMENT '已停车辆数',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='停车场表';
-- 2. 创建车型参数表
CREATE TABLE IF NOT EXISTS `asset_vehicle_model` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`brand` int NOT NULL COMMENT '品牌(字典)',
`model` int NOT NULL COMMENT '车型(字典)',
`model_code` varchar(50) DEFAULT NULL COMMENT '车型编号',
`model_name` varchar(100) NOT NULL COMMENT '车型名称',
`notice_model` varchar(100) DEFAULT NULL COMMENT '车辆公告型号',
`hydrogen_unit` int DEFAULT NULL COMMENT '仪表盘氢气单位(字典)',
`hydrogen_capacity` int DEFAULT NULL COMMENT '氢瓶容量(L)',
`electricity_mileage` int DEFAULT NULL COMMENT '电池公告可行驶里程(KM)',
`reserve_electricity` decimal(10,2) DEFAULT NULL COMMENT '储电量(kwh)',
`hydrogen_mileage` int DEFAULT NULL COMMENT '氢气公告可行驶里程(KM)',
`fuel_type` int DEFAULT NULL COMMENT '燃料种类(字典)',
`tire_size` varchar(50) DEFAULT NULL COMMENT '轮胎尺寸',
`tire_number` int DEFAULT NULL COMMENT '轮胎数量',
`truck_size` varchar(100) DEFAULT NULL COMMENT '车辆尺寸',
`online_spread_enterprise` varchar(100) DEFAULT NULL COMMENT '电堆厂家',
`battery_factory` varchar(100) DEFAULT NULL COMMENT '电池厂家',
`refrigerator_factory` varchar(100) DEFAULT NULL COMMENT '冷机厂家',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`),
KEY `idx_brand` (`brand`),
KEY `idx_model` (`model`),
KEY `idx_model_name` (`model_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='车型参数表';
-- 3. 创建车型维保项目关联表
CREATE TABLE IF NOT EXISTS `asset_vehicle_model_maintain_item` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`vehicle_model_id` bigint NOT NULL COMMENT '车型ID',
`maintain_item_id` bigint NOT NULL COMMENT '维保项目ID',
`maintain_item` varchar(100) DEFAULT NULL COMMENT '保养项目',
`maintain_content` varchar(500) DEFAULT NULL COMMENT '保养内容',
`materials_expenses` decimal(10,2) DEFAULT NULL COMMENT '材料费',
`hour_fee` decimal(10,2) DEFAULT NULL COMMENT '工时费',
`kilometer_cycle` int DEFAULT NULL COMMENT '保养公里周期(KM)',
`time_cycle` int DEFAULT NULL COMMENT '保养时间周期(月)',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`),
KEY `idx_vehicle_model_id` (`vehicle_model_id`),
KEY `idx_maintain_item_id` (`maintain_item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='车型维保项目关联表';

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-asset</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>资产管理模块,包含车辆、合同、备车、交车、还车、替换车等功能</description>
<url>https://github.com/YunaiV/yudao-cloud</url>
<modules>
<module>yudao-module-asset-api</module>
<module>yudao-module-asset-server</module>
</modules>
</project>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yudao-module-asset</artifactId>
<groupId>cn.iocoder.cloud</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-asset-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>资产管理 API定义 Feign 接口等</description>
<url>https://github.com/YunaiV/yudao-cloud</url>
<dependencies>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yudao-module-asset</artifactId>
<groupId>cn.iocoder.cloud</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-asset-server</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>资产管理业务实现</description>
<url>https://github.com/YunaiV/yudao-cloud</url>
<dependencies>
<!-- 资产管理 API -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-asset-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 系统模块 API -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-system-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 工作流模块 API -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-bpm-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 基础设施模块 API -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-infra-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- Spring Cloud 基础 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-rpc</artifactId>
</dependency>
<!-- Registry 注册中心相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Config 配置中心相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- Job 定时任务相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-job</artifactId>
</dependency>
<!-- 消息队列相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-mq</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId>
</dependency>
</dependencies>
<build>
<!-- 设置构建的 jar 包名 -->
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.asset;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 资产管理模块 Application
*
* @author 芋道源码
*/
@SpringBootApplication
public class AssetServerApplication {
public static void main(String[] args) {
SpringApplication.run(AssetServerApplication.class, args);
}
}

View File

@@ -0,0 +1,84 @@
package cn.iocoder.yudao.module.asset.controller.admin.parking;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.asset.controller.admin.parking.vo.*;
import cn.iocoder.yudao.module.asset.dal.dataobject.parking.ParkingDO;
import cn.iocoder.yudao.module.asset.service.parking.ParkingService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* 停车场管理 Controller
*
* @author 芋道源码
*/
@Tag(name = "管理后台 - 停车场管理")
@RestController
@RequestMapping("/asset/parking")
@Validated
public class ParkingController {
@Resource
private ParkingService parkingService;
@PostMapping("/create")
@Operation(summary = "创建停车场")
@PreAuthorize("@ss.hasPermission('asset:parking:create')")
public CommonResult<Long> createParking(@Valid @RequestBody ParkingSaveReqVO createReqVO) {
return success(parkingService.createParking(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新停车场")
@PreAuthorize("@ss.hasPermission('asset:parking:update')")
public CommonResult<Boolean> updateParking(@Valid @RequestBody ParkingSaveReqVO updateReqVO) {
parkingService.updateParking(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除停车场")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('asset:parking:delete')")
public CommonResult<Boolean> deleteParking(@RequestParam("id") Long id) {
parkingService.deleteParking(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得停车场")
@Parameter(name = "id", description = "编号", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('asset:parking:query')")
public CommonResult<ParkingRespVO> getParking(@RequestParam("id") Long id) {
ParkingDO parking = parkingService.getParking(id);
return success(BeanUtils.toBean(parking, ParkingRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得停车场分页")
@PreAuthorize("@ss.hasPermission('asset:parking:query')")
public CommonResult<PageResult<ParkingRespVO>> getParkingPage(@Valid ParkingPageReqVO pageReqVO) {
PageResult<ParkingDO> pageResult = parkingService.getParkingPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ParkingRespVO.class));
}
@GetMapping("/simple-list")
@Operation(summary = "获得停车场精简列表", description = "用于下拉选择")
public CommonResult<List<ParkingSimpleRespVO>> getParkingSimpleList() {
List<ParkingDO> list = parkingService.getParkingSimpleList();
return success(BeanUtils.toBean(list, ParkingSimpleRespVO.class));
}
}

View File

@@ -0,0 +1,74 @@
package cn.iocoder.yudao.module.asset.controller.admin.parking.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotBlank;
import java.time.LocalDate;
/**
* 停车场 Base VO
*
* @author 芋道源码
*/
@Data
public class ParkingBaseVO {
@Schema(description = "停车场名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张江停车场")
@NotBlank(message = "停车场名称不能为空")
private String name;
@Schema(description = "地址", example = "上海市浦东新区张江高科技园区")
private String address;
@Schema(description = "容量", example = "100")
@jakarta.validation.constraints.Min(value = 1, message = "容量必须大于0")
private Integer capacity;
@Schema(description = "省份", example = "浙江省")
private String province;
@Schema(description = "城市", example = "嘉兴市")
private String city;
@Schema(description = "租赁开始时间", example = "2026-01-01")
private LocalDate leaseStartDate;
@Schema(description = "租赁结束时间", example = "2027-01-01")
private LocalDate leaseEndDate;
@Schema(description = "负责人", example = "张三")
private String managerName;
@Schema(description = "负责人联系方式", example = "13800138000")
private String managerPhone;
@Schema(description = "停车场联系人", example = "李四")
private String contactName;
@Schema(description = "停车场联系方式", example = "13900139000")
private String contactPhone;
@Schema(description = "公司负责人", example = "王五")
private String principal;
@Schema(description = "已停车辆数", example = "50")
@jakarta.validation.constraints.Min(value = 0, message = "已停车辆数不能为负数")
private Integer parkedAmount;
@Schema(description = "库存区域(字典)", example = "1")
private Integer stockArea;
@Schema(description = "异动城市(字典)", example = "1")
private Integer unusualActionCity;
@Schema(description = "经度", example = "120.123456")
private String longitude;
@Schema(description = "纬度", example = "30.123456")
private String latitude;
@Schema(description = "备注", example = "备注信息")
private String remark;
}

View File

@@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.asset.controller.admin.parking.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 停车场 - 分页查询 Request VO
*
* @author 芋道源码
*/
@Schema(description = "管理后台 - 停车场分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ParkingPageReqVO extends PageParam {
@Schema(description = "停车场名称", example = "张江停车场")
private String name;
@Schema(description = "地址", example = "上海市浦东新区")
private String address;
@Schema(description = "省份", example = "浙江省")
private String province;
@Schema(description = "城市", example = "嘉兴市")
private String city;
@Schema(description = "负责人", example = "张三")
private String managerName;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.asset.controller.admin.parking.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
/**
* 停车场 - Response VO
*
* @author 芋道源码
*/
@Schema(description = "管理后台 - 停车场 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ParkingRespVO extends ParkingBaseVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.asset.controller.admin.parking.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* 停车场 - 创建/更新 Request VO
*
* @author 芋道源码
*/
@Schema(description = "管理后台 - 停车场创建/更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ParkingSaveReqVO extends ParkingBaseVO {
@Schema(description = "主键", example = "1")
private Long id;
}

View File

@@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.asset.controller.admin.parking.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 停车场 - 精简信息 Response VO
* 用于下拉选择
*
* @author 芋道源码
*/
@Schema(description = "管理后台 - 停车场精简信息 Response VO")
@Data
public class ParkingSimpleRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "停车场名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张江停车场")
private String name;
}

View File

@@ -0,0 +1,107 @@
package cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo.*;
import cn.iocoder.yudao.module.asset.dal.dataobject.vehiclemodel.VehicleModelDO;
import cn.iocoder.yudao.module.asset.dal.dataobject.vehiclemodel.VehicleModelMaintainItemDO;
import cn.iocoder.yudao.module.asset.service.vehiclemodel.VehicleModelService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* 车型参数 Controller
*
* @author 芋道源码
*/
@Tag(name = "管理后台 - 车型参数")
@RestController
@RequestMapping("/asset/vehicle-model")
@Validated
public class VehicleModelController {
@Resource
private VehicleModelService vehicleModelService;
@PostMapping("/create")
@Operation(summary = "创建车型参数")
@PreAuthorize("@ss.hasPermission('asset:vehicle-model:create')")
public CommonResult<Long> createVehicleModel(@Valid @RequestBody VehicleModelSaveReqVO createReqVO) {
return success(vehicleModelService.createVehicleModel(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新车型参数")
@PreAuthorize("@ss.hasPermission('asset:vehicle-model:update')")
public CommonResult<Boolean> updateVehicleModel(@Valid @RequestBody VehicleModelSaveReqVO updateReqVO) {
vehicleModelService.updateVehicleModel(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除车型参数")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('asset:vehicle-model:delete')")
public CommonResult<Boolean> deleteVehicleModel(@RequestParam("id") Long id) {
vehicleModelService.deleteVehicleModel(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得车型参数")
@Parameter(name = "id", description = "编号", required = true, example = "1")
@PreAuthorize("@ss.hasPermission('asset:vehicle-model:query')")
public CommonResult<VehicleModelRespVO> getVehicleModel(@RequestParam("id") Long id) {
VehicleModelDO vehicleModel = vehicleModelService.getVehicleModel(id);
VehicleModelRespVO respVO = BeanUtils.toBean(vehicleModel, VehicleModelRespVO.class);
// 获取维保项目列表
List<VehicleModelMaintainItemDO> maintainItems = vehicleModelService.getVehicleModelMaintainItems(id);
respVO.setMaintainItems(BeanUtils.toBean(maintainItems, VehicleModelMaintainItemVO.class));
return success(respVO);
}
@GetMapping("/page")
@Operation(summary = "获得车型参数分页")
@PreAuthorize("@ss.hasPermission('asset:vehicle-model:query')")
public CommonResult<PageResult<VehicleModelRespVO>> getVehicleModelPage(@Valid VehicleModelPageReqVO pageReqVO) {
PageResult<VehicleModelDO> pageResult = vehicleModelService.getVehicleModelPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, VehicleModelRespVO.class));
}
@GetMapping("/simple-list")
@Operation(summary = "获得车型参数精简列表", description = "用于下拉选择")
public CommonResult<List<VehicleModelSimpleRespVO>> getVehicleModelSimpleList() {
List<VehicleModelDO> list = vehicleModelService.getVehicleModelSimpleList();
return success(BeanUtils.toBean(list, VehicleModelSimpleRespVO.class));
}
@GetMapping("/list-by-brand")
@Operation(summary = "根据品牌获取车型参数列表")
@Parameter(name = "brand", description = "品牌", required = true)
public CommonResult<List<VehicleModelRespVO>> getVehicleModelListByBrand(@RequestParam("brand") Integer brand) {
List<VehicleModelDO> list = vehicleModelService.getVehicleModelListByBrand(brand);
return success(BeanUtils.toBean(list, VehicleModelRespVO.class));
}
@GetMapping("/list-by-model")
@Operation(summary = "根据车型获取车型参数列表")
@Parameter(name = "model", description = "车型", required = true)
public CommonResult<List<VehicleModelRespVO>> getVehicleModelListByModel(@RequestParam("model") Integer model) {
List<VehicleModelDO> list = vehicleModelService.getVehicleModelListByModel(model);
return success(BeanUtils.toBean(list, VehicleModelRespVO.class));
}
}

View File

@@ -0,0 +1,72 @@
package cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* 车型参数 Base VO
*
* @author 芋道源码
*/
@Data
public class VehicleModelBaseVO {
@Schema(description = "品牌(字典)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "品牌不能为空")
private Integer brand;
@Schema(description = "车型(字典)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "车型不能为空")
private Integer model;
@Schema(description = "车型编号", example = "HFC1043K1")
private String modelCode;
@Schema(description = "车型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "江淮骏铃V6")
@NotBlank(message = "车型名称不能为空")
private String modelName;
@Schema(description = "车辆公告型号", example = "HFC1043K1R8T")
private String noticeModel;
@Schema(description = "仪表盘氢气单位(字典)", example = "1")
private Integer hydrogenUnit;
@Schema(description = "氢瓶容量(L)", example = "165")
private Integer hydrogenCapacity;
@Schema(description = "电池公告可行驶里程(KM)", example = "300")
private Integer electricityMileage;
@Schema(description = "储电量(kwh)", example = "80.00")
private BigDecimal reserveElectricity;
@Schema(description = "氢气公告可行驶里程(KM)", example = "400")
private Integer hydrogenMileage;
@Schema(description = "燃料种类(字典)", example = "1")
private Integer fuelType;
@Schema(description = "轮胎尺寸", example = "225/70R19.5")
private String tireSize;
@Schema(description = "轮胎数量", example = "6")
private Integer tireNumber;
@Schema(description = "车辆尺寸", example = "5995×2100×2850")
private String truckSize;
@Schema(description = "电堆厂家", example = "上海重塑")
private String onlineSpreadEnterprise;
@Schema(description = "电池厂家", example = "宁德时代")
private String batteryFactory;
@Schema(description = "冷机厂家", example = "开山")
private String refrigeratorFactory;
}

View File

@@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
/**
* 车型维保项目 VO
*
* @author 芋道源码
*/
@Schema(description = "管理后台 - 车型维保项目 VO")
@Data
public class VehicleModelMaintainItemVO {
@Schema(description = "主键", example = "1")
private Long id;
@Schema(description = "维保项目ID", example = "1")
private Long maintainItemId;
@Schema(description = "保养项目", example = "更换机油")
private String maintainItem;
@Schema(description = "保养内容", example = "更换机油、机滤")
private String maintainContent;
@Schema(description = "材料费", example = "200.00")
private BigDecimal materialsExpenses;
@Schema(description = "工时费", example = "100.00")
private BigDecimal hourFee;
@Schema(description = "保养公里周期(KM)", example = "5000")
private Integer kilometerCycle;
@Schema(description = "保养时间周期(月)", example = "6")
private Integer timeCycle;
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* 车型参数分页 Request VO
*
* @author 芋道源码
*/
@Schema(description = "管理后台 - 车型参数分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class VehicleModelPageReqVO extends PageParam {
@Schema(description = "品牌(字典)", example = "1")
private Integer brand;
@Schema(description = "车型(字典)", example = "1")
private Integer model;
@Schema(description = "车型名称", example = "江淮骏铃V6")
private String modelName;
@Schema(description = "车型编号", example = "HFC1043K1")
private String modelCode;
@Schema(description = "燃料种类(字典)", example = "1")
private Integer fuelType;
}

View File

@@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
import java.util.List;
/**
* 车型参数 Response VO
*
* @author 芋道源码
*/
@Schema(description = "管理后台 - 车型参数 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class VehicleModelRespVO extends VehicleModelBaseVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "维保项目列表")
private List<VehicleModelMaintainItemVO> maintainItems;
}

View File

@@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import jakarta.validation.constraints.NotNull;
import java.util.List;
/**
* 车型参数新增/修改 Request VO
*
* @author 芋道源码
*/
@Schema(description = "管理后台 - 车型参数新增/修改 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class VehicleModelSaveReqVO extends VehicleModelBaseVO {
@Schema(description = "主键", example = "1")
private Long id;
@Schema(description = "维保项目列表")
private List<VehicleModelMaintainItemVO> maintainItems;
}

View File

@@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 车型参数精简 Response VO
*
* @author 芋道源码
*/
@Schema(description = "管理后台 - 车型参数精简 Response VO")
@Data
public class VehicleModelSimpleRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long id;
@Schema(description = "车型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "江淮骏铃V6")
private String modelName;
@Schema(description = "品牌(字典)", example = "1")
private Integer brand;
@Schema(description = "车型(字典)", example = "1")
private Integer model;
}

View File

@@ -0,0 +1,122 @@
package cn.iocoder.yudao.module.asset.dal.dataobject.parking;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.time.LocalDate;
/**
* 停车场 DO
*
* @author 芋道源码
*/
@TableName("asset_parking")
@KeySequence("asset_parking_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ParkingDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 停车场名称
*/
private String name;
/**
* 地址
*/
private String address;
/**
* 容量
*/
private Integer capacity;
/**
* 省份
*/
private String province;
/**
* 城市
*/
private String city;
/**
* 租赁开始时间
*/
private LocalDate leaseStartDate;
/**
* 租赁结束时间
*/
private LocalDate leaseEndDate;
/**
* 负责人
*/
private String managerName;
/**
* 负责人联系方式
*/
private String managerPhone;
/**
* 停车场联系人
*/
private String contactName;
/**
* 停车场联系方式
*/
private String contactPhone;
/**
* 公司负责人
*/
private String principal;
/**
* 已停车辆数
*/
private Integer parkedAmount;
/**
* 库存区域(字典)
*/
private Integer stockArea;
/**
* 异动城市(字典)
*/
private Integer unusualActionCity;
/**
* 经度
*/
private String longitude;
/**
* 纬度
*/
private String latitude;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,117 @@
package cn.iocoder.yudao.module.asset.dal.dataobject.vehiclemodel;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.math.BigDecimal;
/**
* 车型参数 DO
*
* @author 芋道源码
*/
@TableName("asset_vehicle_model")
@KeySequence("asset_vehicle_model_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VehicleModelDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 品牌(字典)
*/
private Integer brand;
/**
* 车型(字典)
*/
private Integer model;
/**
* 车型编号
*/
private String modelCode;
/**
* 车型名称
*/
private String modelName;
/**
* 车辆公告型号
*/
private String noticeModel;
/**
* 仪表盘氢气单位(字典)
*/
private Integer hydrogenUnit;
/**
* 氢瓶容量(L)
*/
private Integer hydrogenCapacity;
/**
* 电池公告可行驶里程(KM)
*/
private Integer electricityMileage;
/**
* 储电量(kwh)
*/
private BigDecimal reserveElectricity;
/**
* 氢气公告可行驶里程(KM)
*/
private Integer hydrogenMileage;
/**
* 燃料种类(字典)
*/
private Integer fuelType;
/**
* 轮胎尺寸
*/
private String tireSize;
/**
* 轮胎数量
*/
private Integer tireNumber;
/**
* 车辆尺寸
*/
private String truckSize;
/**
* 电堆厂家
*/
private String onlineSpreadEnterprise;
/**
* 电池厂家
*/
private String batteryFactory;
/**
* 冷机厂家
*/
private String refrigeratorFactory;
}

View File

@@ -0,0 +1,72 @@
package cn.iocoder.yudao.module.asset.dal.dataobject.vehiclemodel;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.math.BigDecimal;
/**
* 车型维保项目关联 DO
*
* @author 芋道源码
*/
@TableName("asset_vehicle_model_maintain_item")
@KeySequence("asset_vehicle_model_maintain_item_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VehicleModelMaintainItemDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 车型ID
*/
private Long vehicleModelId;
/**
* 维保项目ID
*/
private Long maintainItemId;
/**
* 保养项目
*/
private String maintainItem;
/**
* 保养内容
*/
private String maintainContent;
/**
* 材料费
*/
private BigDecimal materialsExpenses;
/**
* 工时费
*/
private BigDecimal hourFee;
/**
* 保养公里周期(KM)
*/
private Integer kilometerCycle;
/**
* 保养时间周期(月)
*/
private Integer timeCycle;
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.asset.dal.mysql.parking;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.asset.controller.admin.parking.vo.ParkingPageReqVO;
import cn.iocoder.yudao.module.asset.dal.dataobject.parking.ParkingDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 停车场 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface ParkingMapper extends BaseMapperX<ParkingDO> {
default PageResult<ParkingDO> selectPage(ParkingPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ParkingDO>()
.likeIfPresent(ParkingDO::getName, reqVO.getName())
.likeIfPresent(ParkingDO::getAddress, reqVO.getAddress())
.likeIfPresent(ParkingDO::getProvince, reqVO.getProvince())
.likeIfPresent(ParkingDO::getCity, reqVO.getCity())
.likeIfPresent(ParkingDO::getManagerName, reqVO.getManagerName())
.betweenIfPresent(ParkingDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ParkingDO::getId));
}
default List<ParkingDO> selectSimpleList() {
return selectList();
}
}

View File

@@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.asset.dal.mysql.vehiclemodel;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.asset.dal.dataobject.vehiclemodel.VehicleModelMaintainItemDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 车型维保项目关联 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface VehicleModelMaintainItemMapper extends BaseMapperX<VehicleModelMaintainItemDO> {
default List<VehicleModelMaintainItemDO> selectListByVehicleModelId(Long vehicleModelId) {
return selectList(VehicleModelMaintainItemDO::getVehicleModelId, vehicleModelId);
}
default void deleteByVehicleModelId(Long vehicleModelId) {
delete(VehicleModelMaintainItemDO::getVehicleModelId, vehicleModelId);
}
}

View File

@@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.asset.dal.mysql.vehiclemodel;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo.VehicleModelPageReqVO;
import cn.iocoder.yudao.module.asset.dal.dataobject.vehiclemodel.VehicleModelDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 车型参数 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface VehicleModelMapper extends BaseMapperX<VehicleModelDO> {
default PageResult<VehicleModelDO> selectPage(VehicleModelPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<VehicleModelDO>()
.eqIfPresent(VehicleModelDO::getBrand, reqVO.getBrand())
.eqIfPresent(VehicleModelDO::getModel, reqVO.getModel())
.likeIfPresent(VehicleModelDO::getModelName, reqVO.getModelName())
.likeIfPresent(VehicleModelDO::getModelCode, reqVO.getModelCode())
.eqIfPresent(VehicleModelDO::getFuelType, reqVO.getFuelType())
.orderByDesc(VehicleModelDO::getId));
}
default List<VehicleModelDO> selectListByBrand(Integer brand) {
return selectList(VehicleModelDO::getBrand, brand);
}
default List<VehicleModelDO> selectListByModel(Integer model) {
return selectList(VehicleModelDO::getModel, model);
}
}

View File

@@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.asset.enums;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
* Asset 错误码枚举类
*
* asset 系统,使用 1-008-000-000 段
*/
public interface ErrorCodeConstants {
// ========== 停车场管理 1-008-001-000 ==========
ErrorCode PARKING_NOT_EXISTS = new ErrorCode(1_008_001_000, "停车场不存在");
ErrorCode PARKING_PARKED_AMOUNT_EXCEED_CAPACITY = new ErrorCode(1_008_001_001, "已停车辆数不能超过容量");
ErrorCode PARKING_LEASE_END_DATE_BEFORE_START_DATE = new ErrorCode(1_008_001_002, "租赁结束时间不能早于开始时间");
// ========== 车型参数管理 1-008-002-000 ==========
ErrorCode VEHICLE_MODEL_NOT_EXISTS = new ErrorCode(1_008_002_000, "车型参数不存在");
}

View File

@@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.asset.service.parking;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.asset.controller.admin.parking.vo.ParkingPageReqVO;
import cn.iocoder.yudao.module.asset.controller.admin.parking.vo.ParkingSaveReqVO;
import cn.iocoder.yudao.module.asset.dal.dataobject.parking.ParkingDO;
import jakarta.validation.Valid;
import java.util.List;
/**
* 停车场 Service 接口
*
* @author 芋道源码
*/
public interface ParkingService {
/**
* 创建停车场
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createParking(@Valid ParkingSaveReqVO createReqVO);
/**
* 更新停车场
*
* @param updateReqVO 更新信息
*/
void updateParking(@Valid ParkingSaveReqVO updateReqVO);
/**
* 删除停车场
*
* @param id 编号
*/
void deleteParking(Long id);
/**
* 获得停车场
*
* @param id 编号
* @return 停车场
*/
ParkingDO getParking(Long id);
/**
* 获得停车场分页
*
* @param pageReqVO 分页查询
* @return 停车场分页
*/
PageResult<ParkingDO> getParkingPage(ParkingPageReqVO pageReqVO);
/**
* 获得停车场精简列表
*
* @return 停车场列表
*/
List<ParkingDO> getParkingSimpleList();
}

View File

@@ -0,0 +1,97 @@
package cn.iocoder.yudao.module.asset.service.parking;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.asset.controller.admin.parking.vo.ParkingPageReqVO;
import cn.iocoder.yudao.module.asset.controller.admin.parking.vo.ParkingSaveReqVO;
import cn.iocoder.yudao.module.asset.dal.dataobject.parking.ParkingDO;
import cn.iocoder.yudao.module.asset.dal.mysql.parking.ParkingMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import jakarta.annotation.Resource;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.asset.enums.ErrorCodeConstants.*;
/**
* 停车场 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class ParkingServiceImpl implements ParkingService {
@Resource
private ParkingMapper parkingMapper;
@Override
public Long createParking(ParkingSaveReqVO createReqVO) {
// 业务校验
validateParkingBusiness(createReqVO);
ParkingDO parking = BeanUtils.toBean(createReqVO, ParkingDO.class);
parkingMapper.insert(parking);
return parking.getId();
}
@Override
public void updateParking(ParkingSaveReqVO updateReqVO) {
validateParkingExists(updateReqVO.getId());
// 业务校验
validateParkingBusiness(updateReqVO);
ParkingDO updateObj = BeanUtils.toBean(updateReqVO, ParkingDO.class);
parkingMapper.updateById(updateObj);
}
@Override
public void deleteParking(Long id) {
validateParkingExists(id);
parkingMapper.deleteById(id);
}
private void validateParkingExists(Long id) {
if (parkingMapper.selectById(id) == null) {
throw exception(PARKING_NOT_EXISTS);
}
}
/**
* 业务校验
*/
private void validateParkingBusiness(ParkingSaveReqVO reqVO) {
// 校验已停车辆数不能超过容量
if (reqVO.getCapacity() != null && reqVO.getParkedAmount() != null) {
if (reqVO.getParkedAmount() > reqVO.getCapacity()) {
throw exception(PARKING_PARKED_AMOUNT_EXCEED_CAPACITY);
}
}
// 校验租赁时间
if (reqVO.getLeaseStartDate() != null && reqVO.getLeaseEndDate() != null) {
if (reqVO.getLeaseEndDate().isBefore(reqVO.getLeaseStartDate())) {
throw exception(PARKING_LEASE_END_DATE_BEFORE_START_DATE);
}
}
}
@Override
public ParkingDO getParking(Long id) {
return parkingMapper.selectById(id);
}
@Override
public PageResult<ParkingDO> getParkingPage(ParkingPageReqVO pageReqVO) {
return parkingMapper.selectPage(pageReqVO);
}
@Override
public List<ParkingDO> getParkingSimpleList() {
return parkingMapper.selectSimpleList();
}
}

View File

@@ -0,0 +1,88 @@
package cn.iocoder.yudao.module.asset.service.vehiclemodel;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo.VehicleModelPageReqVO;
import cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo.VehicleModelSaveReqVO;
import cn.iocoder.yudao.module.asset.dal.dataobject.vehiclemodel.VehicleModelDO;
import cn.iocoder.yudao.module.asset.dal.dataobject.vehiclemodel.VehicleModelMaintainItemDO;
import jakarta.validation.Valid;
import java.util.List;
/**
* 车型参数 Service 接口
*
* @author 芋道源码
*/
public interface VehicleModelService {
/**
* 创建车型参数
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createVehicleModel(@Valid VehicleModelSaveReqVO createReqVO);
/**
* 更新车型参数
*
* @param updateReqVO 更新信息
*/
void updateVehicleModel(@Valid VehicleModelSaveReqVO updateReqVO);
/**
* 删除车型参数
*
* @param id 编号
*/
void deleteVehicleModel(Long id);
/**
* 获得车型参数
*
* @param id 编号
* @return 车型参数
*/
VehicleModelDO getVehicleModel(Long id);
/**
* 获得车型参数分页
*
* @param pageReqVO 分页查询
* @return 车型参数分页
*/
PageResult<VehicleModelDO> getVehicleModelPage(VehicleModelPageReqVO pageReqVO);
/**
* 获得车型参数精简列表
*
* @return 车型参数列表
*/
List<VehicleModelDO> getVehicleModelSimpleList();
/**
* 根据品牌获取车型参数列表
*
* @param brand 品牌
* @return 车型参数列表
*/
List<VehicleModelDO> getVehicleModelListByBrand(Integer brand);
/**
* 根据车型获取车型参数列表
*
* @param model 车型
* @return 车型参数列表
*/
List<VehicleModelDO> getVehicleModelListByModel(Integer model);
/**
* 获取车型的维保项目列表
*
* @param vehicleModelId 车型ID
* @return 维保项目列表
*/
List<VehicleModelMaintainItemDO> getVehicleModelMaintainItems(Long vehicleModelId);
}

View File

@@ -0,0 +1,132 @@
package cn.iocoder.yudao.module.asset.service.vehiclemodel;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo.VehicleModelMaintainItemVO;
import cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo.VehicleModelPageReqVO;
import cn.iocoder.yudao.module.asset.controller.admin.vehiclemodel.vo.VehicleModelSaveReqVO;
import cn.iocoder.yudao.module.asset.dal.dataobject.vehiclemodel.VehicleModelDO;
import cn.iocoder.yudao.module.asset.dal.dataobject.vehiclemodel.VehicleModelMaintainItemDO;
import cn.iocoder.yudao.module.asset.dal.mysql.vehiclemodel.VehicleModelMapper;
import cn.iocoder.yudao.module.asset.dal.mysql.vehiclemodel.VehicleModelMaintainItemMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.asset.enums.ErrorCodeConstants.VEHICLE_MODEL_NOT_EXISTS;
/**
* 车型参数 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class VehicleModelServiceImpl implements VehicleModelService {
@Resource
private VehicleModelMapper vehicleModelMapper;
@Resource
private VehicleModelMaintainItemMapper vehicleModelMaintainItemMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createVehicleModel(VehicleModelSaveReqVO createReqVO) {
// 插入车型参数
VehicleModelDO vehicleModel = BeanUtils.toBean(createReqVO, VehicleModelDO.class);
vehicleModelMapper.insert(vehicleModel);
// 插入维保项目
saveMaintainItems(vehicleModel.getId(), createReqVO.getMaintainItems());
// 返回
return vehicleModel.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateVehicleModel(VehicleModelSaveReqVO updateReqVO) {
// 校验存在
validateVehicleModelExists(updateReqVO.getId());
// 更新车型参数
VehicleModelDO updateObj = BeanUtils.toBean(updateReqVO, VehicleModelDO.class);
vehicleModelMapper.updateById(updateObj);
// 删除旧的维保项目
vehicleModelMaintainItemMapper.deleteByVehicleModelId(updateReqVO.getId());
// 插入新的维保项目
saveMaintainItems(updateReqVO.getId(), updateReqVO.getMaintainItems());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteVehicleModel(Long id) {
// 校验存在
validateVehicleModelExists(id);
// 删除车型参数
vehicleModelMapper.deleteById(id);
// 删除维保项目
vehicleModelMaintainItemMapper.deleteByVehicleModelId(id);
}
private void validateVehicleModelExists(Long id) {
if (vehicleModelMapper.selectById(id) == null) {
throw exception(VEHICLE_MODEL_NOT_EXISTS);
}
}
@Override
public VehicleModelDO getVehicleModel(Long id) {
return vehicleModelMapper.selectById(id);
}
@Override
public PageResult<VehicleModelDO> getVehicleModelPage(VehicleModelPageReqVO pageReqVO) {
return vehicleModelMapper.selectPage(pageReqVO);
}
@Override
public List<VehicleModelDO> getVehicleModelSimpleList() {
return vehicleModelMapper.selectList();
}
@Override
public List<VehicleModelDO> getVehicleModelListByBrand(Integer brand) {
return vehicleModelMapper.selectListByBrand(brand);
}
@Override
public List<VehicleModelDO> getVehicleModelListByModel(Integer model) {
return vehicleModelMapper.selectListByModel(model);
}
@Override
public List<VehicleModelMaintainItemDO> getVehicleModelMaintainItems(Long vehicleModelId) {
return vehicleModelMaintainItemMapper.selectListByVehicleModelId(vehicleModelId);
}
/**
* 保存维保项目
*/
private void saveMaintainItems(Long vehicleModelId, List<VehicleModelMaintainItemVO> maintainItems) {
if (maintainItems == null || maintainItems.isEmpty()) {
return;
}
for (VehicleModelMaintainItemVO item : maintainItems) {
VehicleModelMaintainItemDO maintainItem = BeanUtils.toBean(item, VehicleModelMaintainItemDO.class);
maintainItem.setVehicleModelId(vehicleModelId);
vehicleModelMaintainItemMapper.insert(maintainItem);
}
}
}

View File

@@ -0,0 +1,111 @@
server:
port: 48084
spring:
application:
name: asset-server
# 允许 Bean 覆盖
main:
allow-bean-definition-overriding: true
# 禁用 Nacos 配置中心
cloud:
nacos:
config:
enabled: false
import-check:
enabled: false
# 数据源配置
datasource:
druid:
url: jdbc:mysql://47.103.115.36:3306/oneos_asset?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: Passw0rd2026
driver-class-name: com.mysql.cj.jdbc.Driver
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
test-while-idle: true
test-on-borrow: false
test-on-return: false
# Redis 配置
data:
redis:
host: 47.103.115.36
port: 6379
database: 0
password: Passw0rd2026
timeout: 10s
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: -1ms
# MyBatis Plus 配置
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
type-aliases-package: cn.iocoder.yudao.module.asset.dal.dataobject
# 日志配置
logging:
level:
root: INFO
cn.iocoder.yudao.module.asset: DEBUG
cn.iocoder.yudao.framework: INFO
pattern:
console: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n'
# 芋道配置
yudao:
info:
version: 1.0.0
base-package: cn.iocoder.yudao.module.asset
web:
admin-api:
prefix: /admin-api
controller: '**.controller.admin.**'
admin-ui:
url: http://localhost:3000
security:
permit-all_urls:
- /admin-api/asset/parking/page
- /admin-api/asset/parking/simple-list
- /admin-api/asset/vehicle-model/page
- /admin-api/asset/vehicle-model/simple-list
xss:
enable: false
access-log:
enable: true
error-code:
enable: true
demo: false
tenant:
enable: false
# Swagger 配置
springdoc:
api-docs:
enabled: true
path: /v3/api-docs
swagger-ui:
enabled: true
path: /swagger-ui.html
knife4j:
enable: true
setting:
language: zh_cn

View File

@@ -0,0 +1,89 @@
server:
port: 48083
spring:
application:
name: asset-server
profiles:
active: local
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yaml
shared-configs:
- application-${spring.profiles.active}.yaml
--- #################### 数据库相关配置 ####################
spring:
datasource:
druid:
url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: 123456
# Redis 配置
data:
redis:
host: 127.0.0.1
port: 6379
database: 0
password:
--- #################### 定时任务相关配置 ####################
xxl:
job:
enabled: false
admin:
addresses: http://127.0.0.1:9090/xxl-job-admin
executor:
appname: ${spring.application.name}
logpath: ${user.home}/logs/xxl-job/${spring.application.name}
accessToken: default_token
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项
lock4j:
acquire-timeout: 3000
expire: 30000
--- #################### 监控相关配置 ####################
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: ALWAYS
--- #################### 芋道相关配置 ####################
yudao:
info:
version: 1.0.0
base-package: cn.iocoder.yudao.module.asset
web:
admin-api:
prefix: /admin-api
controller: '**.controller.admin.**'
security:
permit-all_urls:
- /admin-api/asset/truck/page # 车辆分页查询,示例
xss:
enable: false
exclude-urls:
- /admin-api/asset/truck/create # 车辆创建,示例
access-log:
enable: false
error-code:
enable: false
demo: false

View File

@@ -0,0 +1,85 @@
package cn.iocoder.yudao.module.asset.controller.admin.parking;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.asset.controller.admin.parking.vo.ParkingSaveReqVO;
import cn.iocoder.yudao.module.asset.dal.dataobject.parking.ParkingDO;
import cn.iocoder.yudao.module.asset.dal.mysql.parking.ParkingMapper;
import cn.iocoder.yudao.module.asset.service.parking.ParkingServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import jakarta.annotation.Resource;
import static org.junit.jupiter.api.Assertions.*;
/**
* 停车场管理 Service 测试
*/
@Import(ParkingServiceImpl.class)
public class ParkingServiceTest extends BaseDbUnitTest {
@Resource
private ParkingServiceImpl parkingService;
@Resource
private ParkingMapper parkingMapper;
@Test
public void testCreateParking() {
// 准备参数
ParkingSaveReqVO reqVO = new ParkingSaveReqVO();
reqVO.setName("测试停车场");
reqVO.setAddress("上海市浦东新区");
reqVO.setCapacity(100);
reqVO.setParkedAmount(50);
// 调用
Long parkingId = parkingService.createParking(reqVO);
// 断言
assertNotNull(parkingId);
ParkingDO parking = parkingMapper.selectById(parkingId);
assertNotNull(parking);
assertEquals("测试停车场", parking.getName());
assertEquals(100, parking.getCapacity());
}
@Test
public void testUpdateParking() {
// 先创建
ParkingDO parking = new ParkingDO();
parking.setName("原停车场");
parking.setCapacity(50);
parkingMapper.insert(parking);
// 准备更新参数
ParkingSaveReqVO reqVO = new ParkingSaveReqVO();
reqVO.setId(parking.getId());
reqVO.setName("更新后停车场");
reqVO.setCapacity(100);
// 调用
parkingService.updateParking(reqVO);
// 断言
ParkingDO updated = parkingMapper.selectById(parking.getId());
assertEquals("更新后停车场", updated.getName());
assertEquals(100, updated.getCapacity());
}
@Test
public void testDeleteParking() {
// 先创建
ParkingDO parking = new ParkingDO();
parking.setName("待删除停车场");
parkingMapper.insert(parking);
// 调用删除
parkingService.deleteParking(parking.getId());
// 断言
ParkingDO deleted = parkingMapper.selectById(parking.getId());
assertNull(deleted);
}
}