feat(asset): 客户管理模块开发完成
- 新增客户管理 CRUD 功能(个人/企业客户) - 新增 7 个单元测试用例(全部通过) - 新增测试配置和 SQL 脚本 - 车辆管理字段补充(32个新字段) - ECS 部署测试通过
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package cn.iocoder.yudao.module.asset.controller.admin.customer;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerPageReqVO;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerRespVO;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerSaveReqVO;
|
||||
import cn.iocoder.yudao.module.asset.convert.customer.CustomerConvert;
|
||||
import cn.iocoder.yudao.module.asset.dal.dataobject.customer.CustomerDO;
|
||||
import cn.iocoder.yudao.module.asset.service.customer.CustomerService;
|
||||
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 static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 客户信息 Controller
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Tag(name = "管理后台 - 客户管理")
|
||||
@RestController
|
||||
@RequestMapping("/asset/customer")
|
||||
@Validated
|
||||
public class CustomerController {
|
||||
|
||||
@Resource
|
||||
private CustomerService customerService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建客户")
|
||||
@PreAuthorize("@ss.hasPermission('asset:customer:create')")
|
||||
public CommonResult<Long> createCustomer(@Valid @RequestBody CustomerSaveReqVO createReqVO) {
|
||||
return success(customerService.createCustomer(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新客户")
|
||||
@PreAuthorize("@ss.hasPermission('asset:customer:update')")
|
||||
public CommonResult<Boolean> updateCustomer(@Valid @RequestBody CustomerSaveReqVO updateReqVO) {
|
||||
customerService.updateCustomer(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除客户")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('asset:customer:delete')")
|
||||
public CommonResult<Boolean> deleteCustomer(@RequestParam("id") Long id) {
|
||||
customerService.deleteCustomer(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得客户")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1")
|
||||
@PreAuthorize("@ss.hasPermission('asset:customer:query')")
|
||||
public CommonResult<CustomerRespVO> getCustomer(@RequestParam("id") Long id) {
|
||||
CustomerDO customer = customerService.getCustomer(id);
|
||||
return success(CustomerConvert.INSTANCE.convert(customer));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得客户分页")
|
||||
@PreAuthorize("@ss.hasPermission('asset:customer:query')")
|
||||
public CommonResult<PageResult<CustomerRespVO>> getCustomerPage(@Valid CustomerPageReqVO pageReqVO) {
|
||||
PageResult<CustomerDO> pageResult = customerService.getCustomerPage(pageReqVO);
|
||||
return success(CustomerConvert.INSTANCE.convertPage(pageResult));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.asset.controller.admin.customer.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;
|
||||
|
||||
@Schema(description = "管理后台 - 客户分页查询 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class CustomerPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "客户名称(模糊搜索)", example = "张三")
|
||||
private String customerName;
|
||||
|
||||
@Schema(description = "联系电话(模糊搜索)", example = "13800138000")
|
||||
private String contactPhone;
|
||||
|
||||
@Schema(description = "客户类型", example = "0")
|
||||
private Integer customerType;
|
||||
|
||||
@Schema(description = "状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package cn.iocoder.yudao.module.asset.controller.admin.customer.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 客户 Response VO")
|
||||
@Data
|
||||
public class CustomerRespVO {
|
||||
|
||||
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "CUST000001")
|
||||
private String customerNo;
|
||||
|
||||
@Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
|
||||
private String customerName;
|
||||
|
||||
@Schema(description = "客户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
private Integer customerType;
|
||||
|
||||
@Schema(description = "联系人", example = "张三")
|
||||
private String contactPerson;
|
||||
|
||||
@Schema(description = "联系电话", example = "13800138000")
|
||||
private String contactPhone;
|
||||
|
||||
@Schema(description = "联系邮箱", example = "zhangsan@example.com")
|
||||
private String contactEmail;
|
||||
|
||||
@Schema(description = "联系地址", example = "上海市浦东新区")
|
||||
private String contactAddress;
|
||||
|
||||
@Schema(description = "身份证号", example = "310101199001011234")
|
||||
private String idCardNo;
|
||||
|
||||
@Schema(description = "身份证正面照片URL", example = "https://example.com/id_front.jpg")
|
||||
private String idCardFrontUrl;
|
||||
|
||||
@Schema(description = "身份证反面照片URL", example = "https://example.com/id_back.jpg")
|
||||
private String idCardBackUrl;
|
||||
|
||||
@Schema(description = "驾驶证号", example = "310101199001011234")
|
||||
private String driverLicenseNo;
|
||||
|
||||
@Schema(description = "驾驶证照片URL", example = "https://example.com/driver_license.jpg")
|
||||
private String driverLicenseUrl;
|
||||
|
||||
@Schema(description = "企业名称", example = "上海科技有限公司")
|
||||
private String companyName;
|
||||
|
||||
@Schema(description = "统一社会信用代码", example = "91310000MA1FL0001A")
|
||||
private String unifiedSocialCreditCode;
|
||||
|
||||
@Schema(description = "营业执照URL", example = "https://example.com/business_license.jpg")
|
||||
private String businessLicenseUrl;
|
||||
|
||||
@Schema(description = "法人代表", example = "张总")
|
||||
private String legalPerson;
|
||||
|
||||
@Schema(description = "信用等级", example = "1")
|
||||
private Integer creditLevel;
|
||||
|
||||
@Schema(description = "押金金额", example = "5000.00")
|
||||
private BigDecimal depositAmount;
|
||||
|
||||
@Schema(description = "备注", example = "VIP客户")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package cn.iocoder.yudao.module.asset.controller.admin.customer.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import jakarta.validation.constraints.DecimalMin;
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Schema(description = "管理后台 - 客户创建/更新 Request VO")
|
||||
@Data
|
||||
public class CustomerSaveReqVO {
|
||||
|
||||
@Schema(description = "主键ID(更新时必填)", example = "1")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
|
||||
@NotBlank(message = "客户名称不能为空")
|
||||
@Size(max = 100, message = "客户名称长度不能超过100个字符")
|
||||
private String customerName;
|
||||
|
||||
@Schema(description = "客户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||
@NotNull(message = "客户类型不能为空")
|
||||
@Min(value = 0, message = "客户类型值不正确")
|
||||
@Max(value = 1, message = "客户类型值不正确")
|
||||
private Integer customerType;
|
||||
|
||||
@Schema(description = "联系人", example = "张三")
|
||||
@Size(max = 50, message = "联系人长度不能超过50个字符")
|
||||
private String contactPerson;
|
||||
|
||||
@Schema(description = "联系电话", example = "13800138000")
|
||||
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "联系电话格式不正确")
|
||||
private String contactPhone;
|
||||
|
||||
@Schema(description = "联系邮箱", example = "zhangsan@example.com")
|
||||
@Email(message = "联系邮箱格式不正确")
|
||||
@Size(max = 100, message = "联系邮箱长度不能超过100个字符")
|
||||
private String contactEmail;
|
||||
|
||||
@Schema(description = "联系地址", example = "上海市浦东新区")
|
||||
@Size(max = 255, message = "联系地址长度不能超过255个字符")
|
||||
private String contactAddress;
|
||||
|
||||
@Schema(description = "身份证号", example = "310101199001011234")
|
||||
@Pattern(regexp = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$", message = "身份证号格式不正确")
|
||||
private String idCardNo;
|
||||
|
||||
@Schema(description = "身份证正面照片URL", example = "https://example.com/id_front.jpg")
|
||||
@Size(max = 255, message = "身份证正面照片URL长度不能超过255个字符")
|
||||
private String idCardFrontUrl;
|
||||
|
||||
@Schema(description = "身份证反面照片URL", example = "https://example.com/id_back.jpg")
|
||||
@Size(max = 255, message = "身份证反面照片URL长度不能超过255个字符")
|
||||
private String idCardBackUrl;
|
||||
|
||||
@Schema(description = "驾驶证号", example = "310101199001011234")
|
||||
@Size(max = 50, message = "驾驶证号长度不能超过50个字符")
|
||||
private String driverLicenseNo;
|
||||
|
||||
@Schema(description = "驾驶证照片URL", example = "https://example.com/driver_license.jpg")
|
||||
@Size(max = 255, message = "驾驶证照片URL长度不能超过255个字符")
|
||||
private String driverLicenseUrl;
|
||||
|
||||
@Schema(description = "企业名称", example = "上海科技有限公司")
|
||||
@Size(max = 200, message = "企业名称长度不能超过200个字符")
|
||||
private String companyName;
|
||||
|
||||
@Schema(description = "统一社会信用代码", example = "91310000MA1FL0001A")
|
||||
@Pattern(regexp = "^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$", message = "统一社会信用代码格式不正确")
|
||||
private String unifiedSocialCreditCode;
|
||||
|
||||
@Schema(description = "营业执照URL", example = "https://example.com/business_license.jpg")
|
||||
@Size(max = 255, message = "营业执照URL长度不能超过255个字符")
|
||||
private String businessLicenseUrl;
|
||||
|
||||
@Schema(description = "法人代表", example = "张总")
|
||||
@Size(max = 50, message = "法人代表长度不能超过50个字符")
|
||||
private String legalPerson;
|
||||
|
||||
@Schema(description = "信用等级", example = "1")
|
||||
@Min(value = 0, message = "信用等级值不正确")
|
||||
@Max(value = 4, message = "信用等级值不正确")
|
||||
private Integer creditLevel;
|
||||
|
||||
@Schema(description = "押金金额", example = "5000.00")
|
||||
@DecimalMin(value = "0.00", message = "押金金额不能为负数")
|
||||
private BigDecimal depositAmount;
|
||||
|
||||
@Schema(description = "备注", example = "VIP客户")
|
||||
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "状态", example = "0")
|
||||
@Min(value = 0, message = "状态值不正确")
|
||||
@Max(value = 2, message = "状态值不正确")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -14,16 +14,25 @@ public class VehicleRespVO {
|
||||
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long id;
|
||||
|
||||
// ==================== 基础信息(asset_vehicle_base)====================
|
||||
@Schema(description = "车牌号", requiredMode = Schema.RequiredMode.REQUIRED, example = "粤A12345")
|
||||
// ==================== 基础信息 ====================
|
||||
@Schema(description = "车牌号", requiredMode = Schema.RequiredMode.REQUIRED, example = "沪A12345")
|
||||
private String plateNo;
|
||||
|
||||
@Schema(description = "车辆编号", example = "VEH000001")
|
||||
private String vehicleNo;
|
||||
|
||||
@Schema(description = "车辆识别代号(VIN)", example = "LGWEF4A59NS123456")
|
||||
private String vin;
|
||||
|
||||
@Schema(description = "车型ID", example = "1")
|
||||
private Long vehicleModelId;
|
||||
|
||||
@Schema(description = "运营省份", example = "广东省")
|
||||
private String regionProvince;
|
||||
|
||||
@Schema(description = "运营城市", example = "广州市")
|
||||
private String regionCity;
|
||||
|
||||
@Schema(description = "发动机号", example = "ENG12345678")
|
||||
private String engineNo;
|
||||
|
||||
@@ -33,76 +42,138 @@ public class VehicleRespVO {
|
||||
@Schema(description = "采购日期", example = "2023-06-15")
|
||||
private LocalDate purchaseDate;
|
||||
|
||||
@Schema(description = "采购价格", example = "180000.00")
|
||||
@Schema(description = "采购价格", example = "150000.00")
|
||||
private BigDecimal purchasePrice;
|
||||
|
||||
@Schema(description = "车身颜色", example = "白色")
|
||||
private String color;
|
||||
|
||||
@Schema(description = "出厂年份", example = "2023")
|
||||
private String year;
|
||||
|
||||
@Schema(description = "行驶里程(公里)", example = "12580")
|
||||
private Integer mileage;
|
||||
|
||||
// ==================== 位置信息(asset_vehicle_location)====================
|
||||
@Schema(description = "行驶证检验有效期", example = "2025-07")
|
||||
private String inspectExpire;
|
||||
|
||||
@Schema(description = "强制报废期", example = "2038-12-31")
|
||||
private LocalDate scrapDate;
|
||||
|
||||
// ==================== 位置信息 ====================
|
||||
@Schema(description = "停车场ID", example = "1")
|
||||
private Long parkingId;
|
||||
|
||||
@Schema(description = "停车场名称", example = "天河停车场")
|
||||
private String parkingName;
|
||||
|
||||
@Schema(description = "停车位", example = "A1-001")
|
||||
private String parkingSpace;
|
||||
|
||||
@Schema(description = "入场时间", example = "2024-01-15 10:30:00")
|
||||
@Schema(description = "GPS详细地址", example = "广东省广州市天河区天河路100号")
|
||||
private String location;
|
||||
|
||||
@Schema(description = "纬度", example = "23.123456")
|
||||
private BigDecimal latitude;
|
||||
|
||||
@Schema(description = "经度", example = "113.123456")
|
||||
private BigDecimal longitude;
|
||||
|
||||
@Schema(description = "GPS最后上传时间", example = "2024-02-12 14:30:00")
|
||||
private LocalDateTime gpsTime;
|
||||
|
||||
@Schema(description = "入场时间", example = "2024-02-01 10:00:00")
|
||||
private LocalDateTime entryTime;
|
||||
|
||||
@Schema(description = "出场时间", example = "2024-01-20 16:45:00")
|
||||
@Schema(description = "出场时间", example = "2024-02-10 18:00:00")
|
||||
private LocalDateTime exitTime;
|
||||
|
||||
// ==================== 业务信息(asset_vehicle_business)====================
|
||||
// ==================== 业务信息 ====================
|
||||
@Schema(description = "客户ID", example = "1")
|
||||
private Long customerId;
|
||||
|
||||
@Schema(description = "业务部门ID", example = "1")
|
||||
private Long departmentId;
|
||||
|
||||
@Schema(description = "业务负责人ID", example = "1")
|
||||
private Long managerId;
|
||||
|
||||
@Schema(description = "合同ID", example = "1")
|
||||
private Long contractId;
|
||||
|
||||
@Schema(description = "登记所有权", example = "某某租赁公司")
|
||||
private String ownership;
|
||||
|
||||
@Schema(description = "交车日期", example = "2024-01-10")
|
||||
private LocalDate deliveryDate;
|
||||
|
||||
@Schema(description = "还车日期", example = "2024-07-10")
|
||||
@Schema(description = "还车日期", example = "2024-02-01")
|
||||
private LocalDate returnDate;
|
||||
|
||||
@Schema(description = "月租金", example = "3500.00")
|
||||
@Schema(description = "月租金", example = "3000.00")
|
||||
private BigDecimal monthlyRent;
|
||||
|
||||
@Schema(description = "押金", example = "12000.00")
|
||||
@Schema(description = "押金", example = "10000.00")
|
||||
private BigDecimal deposit;
|
||||
|
||||
// ==================== 状态信息(asset_vehicle_status)====================
|
||||
@Schema(description = "车辆状态(0=正常 1=维修中 2=报废)", example = "0")
|
||||
// ==================== 状态信息 ====================
|
||||
@Schema(description = "车辆状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "运营状态", example = "2")
|
||||
private Integer operateStatus;
|
||||
|
||||
@Schema(description = "库位状态", example = "5")
|
||||
private Integer storageStatus;
|
||||
|
||||
@Schema(description = "出库状态", example = "4")
|
||||
private Integer outStatus;
|
||||
|
||||
@Schema(description = "预占状态", example = "0")
|
||||
private Integer preemptStatus;
|
||||
|
||||
@Schema(description = "整备状态", example = "3")
|
||||
private Integer prepareStatus;
|
||||
|
||||
@Schema(description = "过户状态", example = "0")
|
||||
private Integer transferStatus;
|
||||
|
||||
@Schema(description = "维修状态", example = "0")
|
||||
private Integer repairStatus;
|
||||
|
||||
@Schema(description = "证照状态", example = "0")
|
||||
private Integer licenseStatus;
|
||||
|
||||
@Schema(description = "报废状态", example = "0")
|
||||
private Integer scrapStatus;
|
||||
|
||||
@Schema(description = "在线状态", example = "1")
|
||||
private Integer onlineStatus;
|
||||
|
||||
@Schema(description = "是否已备车", example = "true")
|
||||
private Boolean isPrepared;
|
||||
|
||||
@Schema(description = "是否已交车", example = "false")
|
||||
@Schema(description = "是否已交车", example = "true")
|
||||
private Boolean isDelivered;
|
||||
|
||||
@Schema(description = "是否已还车", example = "false")
|
||||
private Boolean isReturned;
|
||||
|
||||
@Schema(description = "上次保养日期", example = "2024-01-05")
|
||||
@Schema(description = "上次保养日期", example = "2024-01-15")
|
||||
private LocalDate lastMaintainDate;
|
||||
|
||||
@Schema(description = "下次保养日期", example = "2024-04-05")
|
||||
@Schema(description = "下次保养日期", example = "2024-07-15")
|
||||
private LocalDate nextMaintainDate;
|
||||
|
||||
@Schema(description = "上次年检日期", example = "2023-12-20")
|
||||
@Schema(description = "上次年检日期", example = "2024-01-01")
|
||||
private LocalDate lastInspectDate;
|
||||
|
||||
@Schema(description = "下次年检日期", example = "2024-12-20")
|
||||
@Schema(description = "下次年检日期", example = "2026-01-01")
|
||||
private LocalDate nextInspectDate;
|
||||
|
||||
@Schema(description = "保险到期日期", example = "2024-12-31")
|
||||
@Schema(description = "保险到期日期", example = "2025-12-31")
|
||||
private LocalDate insuranceExpireDate;
|
||||
|
||||
// ==================== 系统字段 ====================
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.module.asset.convert.customer;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerRespVO;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerSaveReqVO;
|
||||
import cn.iocoder.yudao.module.asset.dal.dataobject.customer.CustomerDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 客户 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface CustomerConvert {
|
||||
|
||||
CustomerConvert INSTANCE = Mappers.getMapper(CustomerConvert.class);
|
||||
|
||||
CustomerDO convert(CustomerSaveReqVO bean);
|
||||
|
||||
CustomerRespVO convert(CustomerDO bean);
|
||||
|
||||
PageResult<CustomerRespVO> convertPage(PageResult<CustomerDO> page);
|
||||
|
||||
}
|
||||
@@ -32,21 +32,32 @@ public interface VehicleConvert {
|
||||
if (base != null) {
|
||||
vo.setId(base.getId());
|
||||
vo.setPlateNo(base.getPlateNo());
|
||||
vo.setVehicleNo(base.getVehicleNo());
|
||||
vo.setVin(base.getVin());
|
||||
vo.setVehicleModelId(base.getVehicleModelId());
|
||||
vo.setRegionProvince(base.getRegionProvince());
|
||||
vo.setRegionCity(base.getRegionCity());
|
||||
vo.setEngineNo(base.getEngineNo());
|
||||
vo.setRegisterDate(base.getRegisterDate());
|
||||
vo.setPurchaseDate(base.getPurchaseDate());
|
||||
vo.setPurchasePrice(base.getPurchasePrice());
|
||||
vo.setColor(base.getColor());
|
||||
vo.setYear(base.getYear());
|
||||
vo.setMileage(base.getMileage());
|
||||
vo.setInspectExpire(base.getInspectExpire());
|
||||
vo.setScrapDate(base.getScrapDate());
|
||||
vo.setCreateTime(base.getCreateTime());
|
||||
}
|
||||
|
||||
// 位置信息
|
||||
if (location != null) {
|
||||
vo.setParkingId(location.getParkingId());
|
||||
vo.setParkingName(location.getParkingName());
|
||||
vo.setParkingSpace(location.getParkingSpace());
|
||||
vo.setLocation(location.getLocation());
|
||||
vo.setLatitude(location.getLatitude());
|
||||
vo.setLongitude(location.getLongitude());
|
||||
vo.setGpsTime(location.getGpsTime());
|
||||
vo.setEntryTime(location.getEntryTime());
|
||||
vo.setExitTime(location.getExitTime());
|
||||
}
|
||||
@@ -54,7 +65,10 @@ public interface VehicleConvert {
|
||||
// 业务信息
|
||||
if (business != null) {
|
||||
vo.setCustomerId(business.getCustomerId());
|
||||
vo.setDepartmentId(business.getDepartmentId());
|
||||
vo.setManagerId(business.getManagerId());
|
||||
vo.setContractId(business.getContractId());
|
||||
vo.setOwnership(business.getOwnership());
|
||||
vo.setDeliveryDate(business.getDeliveryDate());
|
||||
vo.setReturnDate(business.getReturnDate());
|
||||
vo.setMonthlyRent(business.getMonthlyRent());
|
||||
@@ -64,6 +78,16 @@ public interface VehicleConvert {
|
||||
// 状态信息
|
||||
if (status != null) {
|
||||
vo.setStatus(status.getStatus());
|
||||
vo.setOperateStatus(status.getOperateStatus());
|
||||
vo.setStorageStatus(status.getStorageStatus());
|
||||
vo.setOutStatus(status.getOutStatus());
|
||||
vo.setPreemptStatus(status.getPreemptStatus());
|
||||
vo.setPrepareStatus(status.getPrepareStatus());
|
||||
vo.setTransferStatus(status.getTransferStatus());
|
||||
vo.setRepairStatus(status.getRepairStatus());
|
||||
vo.setLicenseStatus(status.getLicenseStatus());
|
||||
vo.setScrapStatus(status.getScrapStatus());
|
||||
vo.setOnlineStatus(status.getOnlineStatus());
|
||||
vo.setIsPrepared(status.getIsPrepared());
|
||||
vo.setIsDelivered(status.getIsDelivered());
|
||||
vo.setIsReturned(status.getIsReturned());
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package cn.iocoder.yudao.module.asset.dal.dataobject.customer;
|
||||
|
||||
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_customer")
|
||||
@KeySequence("asset_customer_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CustomerDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 客户编号
|
||||
*/
|
||||
private String customerNo;
|
||||
|
||||
/**
|
||||
* 客户名称
|
||||
*/
|
||||
private String customerName;
|
||||
|
||||
/**
|
||||
* 客户类型(0=个人 1=企业)
|
||||
*/
|
||||
private Integer customerType;
|
||||
|
||||
/**
|
||||
* 联系人
|
||||
*/
|
||||
private String contactPerson;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
private String contactPhone;
|
||||
|
||||
/**
|
||||
* 联系邮箱
|
||||
*/
|
||||
private String contactEmail;
|
||||
|
||||
/**
|
||||
* 联系地址
|
||||
*/
|
||||
private String contactAddress;
|
||||
|
||||
/**
|
||||
* 身份证号
|
||||
*/
|
||||
private String idCardNo;
|
||||
|
||||
/**
|
||||
* 身份证正面照片URL
|
||||
*/
|
||||
private String idCardFrontUrl;
|
||||
|
||||
/**
|
||||
* 身份证反面照片URL
|
||||
*/
|
||||
private String idCardBackUrl;
|
||||
|
||||
/**
|
||||
* 驾驶证号
|
||||
*/
|
||||
private String driverLicenseNo;
|
||||
|
||||
/**
|
||||
* 驾驶证照片URL
|
||||
*/
|
||||
private String driverLicenseUrl;
|
||||
|
||||
/**
|
||||
* 企业名称
|
||||
*/
|
||||
private String companyName;
|
||||
|
||||
/**
|
||||
* 统一社会信用代码
|
||||
*/
|
||||
private String unifiedSocialCreditCode;
|
||||
|
||||
/**
|
||||
* 营业执照URL
|
||||
*/
|
||||
private String businessLicenseUrl;
|
||||
|
||||
/**
|
||||
* 法人代表
|
||||
*/
|
||||
private String legalPerson;
|
||||
|
||||
/**
|
||||
* 信用等级(0=未评级 1=A级 2=B级 3=C级 4=D级)
|
||||
*/
|
||||
private Integer creditLevel;
|
||||
|
||||
/**
|
||||
* 押金金额
|
||||
*/
|
||||
private BigDecimal depositAmount;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 状态(0=正常 1=冻结 2=黑名单)
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -39,11 +39,26 @@ public class VehicleBaseDO extends BaseDO {
|
||||
*/
|
||||
private String plateNo;
|
||||
|
||||
/**
|
||||
* 车辆编号
|
||||
*/
|
||||
private String vehicleNo;
|
||||
|
||||
/**
|
||||
* 车型ID
|
||||
*/
|
||||
private Long vehicleModelId;
|
||||
|
||||
/**
|
||||
* 运营省份
|
||||
*/
|
||||
private String regionProvince;
|
||||
|
||||
/**
|
||||
* 运营城市
|
||||
*/
|
||||
private String regionCity;
|
||||
|
||||
/**
|
||||
* 发动机号
|
||||
*/
|
||||
@@ -69,9 +84,24 @@ public class VehicleBaseDO extends BaseDO {
|
||||
*/
|
||||
private String color;
|
||||
|
||||
/**
|
||||
* 出厂年份
|
||||
*/
|
||||
private String year;
|
||||
|
||||
/**
|
||||
* 行驶里程(公里)
|
||||
*/
|
||||
private Integer mileage;
|
||||
|
||||
/**
|
||||
* 行驶证检验有效期(格式:YYYY-MM)
|
||||
*/
|
||||
private String inspectExpire;
|
||||
|
||||
/**
|
||||
* 强制报废期
|
||||
*/
|
||||
private LocalDate scrapDate;
|
||||
|
||||
}
|
||||
|
||||
@@ -40,11 +40,26 @@ public class VehicleBusinessDO extends BaseDO {
|
||||
*/
|
||||
private Long customerId;
|
||||
|
||||
/**
|
||||
* 业务部门ID
|
||||
*/
|
||||
private Long departmentId;
|
||||
|
||||
/**
|
||||
* 业务负责人ID
|
||||
*/
|
||||
private Long managerId;
|
||||
|
||||
/**
|
||||
* 合同ID
|
||||
*/
|
||||
private Long contractId;
|
||||
|
||||
/**
|
||||
* 登记所有权
|
||||
*/
|
||||
private String ownership;
|
||||
|
||||
/**
|
||||
* 交车日期
|
||||
*/
|
||||
|
||||
@@ -39,11 +39,36 @@ public class VehicleLocationDO extends BaseDO {
|
||||
*/
|
||||
private Long parkingId;
|
||||
|
||||
/**
|
||||
* 停车场名称(冗余字段)
|
||||
*/
|
||||
private String parkingName;
|
||||
|
||||
/**
|
||||
* 停车位
|
||||
*/
|
||||
private String parkingSpace;
|
||||
|
||||
/**
|
||||
* GPS详细地址
|
||||
*/
|
||||
private String location;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
private java.math.BigDecimal latitude;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
private java.math.BigDecimal longitude;
|
||||
|
||||
/**
|
||||
* GPS最后上传时间
|
||||
*/
|
||||
private LocalDateTime gpsTime;
|
||||
|
||||
/**
|
||||
* 入场时间
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,56 @@ public class VehicleStatusDO extends BaseDO {
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 运营状态(0=待运营 1=库存 2=租赁 3=自营 4=退出运营)
|
||||
*/
|
||||
private Integer operateStatus;
|
||||
|
||||
/**
|
||||
* 库位状态(0=新车入库-待验车 1=新车入库-证照办理 2=库存车-可交付车 3=库存车-不可交付车 4=库存车-呆滞车 5=已交付车-租赁交车 6=已交付车-自营交车 7=已交付车-替换交车 8=退出运营-报废车 9=退出运营-三方退租车 10=退出运营-过户售车)
|
||||
*/
|
||||
private Integer storageStatus;
|
||||
|
||||
/**
|
||||
* 出库状态(0=无 1=异动出库 2=调拨出库 3=展示出库 4=租赁交车 5=自营交车 6=替换交车 7=过户售车 8=外租退车 9=报废出库)
|
||||
*/
|
||||
private Integer outStatus;
|
||||
|
||||
/**
|
||||
* 预占状态(0=未预占 1=已预占)
|
||||
*/
|
||||
private Integer preemptStatus;
|
||||
|
||||
/**
|
||||
* 整备状态(0=无 1=待整备 2=整备中 3=正常)
|
||||
*/
|
||||
private Integer prepareStatus;
|
||||
|
||||
/**
|
||||
* 过户状态(0=无 1=过户中 2=内部过户完成 3=销售过户完成)
|
||||
*/
|
||||
private Integer transferStatus;
|
||||
|
||||
/**
|
||||
* 维修状态(0=正常 1=待服务站接单 2=维修中)
|
||||
*/
|
||||
private Integer repairStatus;
|
||||
|
||||
/**
|
||||
* 证照状态(0=正常 1=异常)
|
||||
*/
|
||||
private Integer licenseStatus;
|
||||
|
||||
/**
|
||||
* 报废状态(0=无 1=报废中 2=已报废)
|
||||
*/
|
||||
private Integer scrapStatus;
|
||||
|
||||
/**
|
||||
* 在线状态(0=离线 1=在线)
|
||||
*/
|
||||
private Integer onlineStatus;
|
||||
|
||||
/**
|
||||
* 是否已备车
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.asset.dal.mysql.customer;
|
||||
|
||||
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.customer.vo.CustomerPageReqVO;
|
||||
import cn.iocoder.yudao.module.asset.dal.dataobject.customer.CustomerDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 客户信息 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface CustomerMapper extends BaseMapperX<CustomerDO> {
|
||||
|
||||
default PageResult<CustomerDO> selectPage(CustomerPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<CustomerDO>()
|
||||
.likeIfPresent(CustomerDO::getCustomerName, reqVO.getCustomerName())
|
||||
.likeIfPresent(CustomerDO::getContactPhone, reqVO.getContactPhone())
|
||||
.eqIfPresent(CustomerDO::getCustomerType, reqVO.getCustomerType())
|
||||
.eqIfPresent(CustomerDO::getStatus, reqVO.getStatus())
|
||||
.orderByDesc(CustomerDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,4 +17,7 @@ public interface ErrorCodeConstants {
|
||||
// ========== 车型参数管理 1-008-002-000 ==========
|
||||
ErrorCode VEHICLE_MODEL_NOT_EXISTS = new ErrorCode(1_008_002_000, "车型参数不存在");
|
||||
|
||||
// ========== 客户管理 1-008-003-000 ==========
|
||||
ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_008_003_000, "客户不存在");
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package cn.iocoder.yudao.module.asset.service.customer;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerPageReqVO;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerSaveReqVO;
|
||||
import cn.iocoder.yudao.module.asset.dal.dataobject.customer.CustomerDO;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
/**
|
||||
* 客户信息 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface CustomerService {
|
||||
|
||||
/**
|
||||
* 创建客户
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createCustomer(@Valid CustomerSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新客户
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateCustomer(@Valid CustomerSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除客户
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteCustomer(Long id);
|
||||
|
||||
/**
|
||||
* 获得客户
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 客户
|
||||
*/
|
||||
CustomerDO getCustomer(Long id);
|
||||
|
||||
/**
|
||||
* 获得客户分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 客户分页
|
||||
*/
|
||||
PageResult<CustomerDO> getCustomerPage(CustomerPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package cn.iocoder.yudao.module.asset.service.customer;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerPageReqVO;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerSaveReqVO;
|
||||
import cn.iocoder.yudao.module.asset.convert.customer.CustomerConvert;
|
||||
import cn.iocoder.yudao.module.asset.dal.dataobject.customer.CustomerDO;
|
||||
import cn.iocoder.yudao.module.asset.dal.mysql.customer.CustomerMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.asset.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 客户信息 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class CustomerServiceImpl implements CustomerService {
|
||||
|
||||
@Resource
|
||||
private CustomerMapper customerMapper;
|
||||
|
||||
@Override
|
||||
public Long createCustomer(CustomerSaveReqVO createReqVO) {
|
||||
// 转换并插入
|
||||
CustomerDO customer = CustomerConvert.INSTANCE.convert(createReqVO);
|
||||
|
||||
// 生成客户编号
|
||||
if (customer.getCustomerNo() == null) {
|
||||
customer.setCustomerNo(generateCustomerNo());
|
||||
}
|
||||
|
||||
customerMapper.insert(customer);
|
||||
return customer.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCustomer(CustomerSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateCustomerExists(updateReqVO.getId());
|
||||
|
||||
// 转换并更新
|
||||
CustomerDO updateObj = CustomerConvert.INSTANCE.convert(updateReqVO);
|
||||
customerMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCustomer(Long id) {
|
||||
// 校验存在
|
||||
validateCustomerExists(id);
|
||||
|
||||
// 删除
|
||||
customerMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateCustomerExists(Long id) {
|
||||
if (customerMapper.selectById(id) == null) {
|
||||
throw exception(CUSTOMER_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomerDO getCustomer(Long id) {
|
||||
return customerMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<CustomerDO> getCustomerPage(CustomerPageReqVO pageReqVO) {
|
||||
return customerMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成客户编号
|
||||
*/
|
||||
private String generateCustomerNo() {
|
||||
// 查询最大ID
|
||||
Long maxId = customerMapper.selectCount();
|
||||
return String.format("CUST%06d", maxId + 1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
package cn.iocoder.yudao.module.asset.service.customer;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerPageReqVO;
|
||||
import cn.iocoder.yudao.module.asset.controller.admin.customer.vo.CustomerSaveReqVO;
|
||||
import cn.iocoder.yudao.module.asset.dal.dataobject.customer.CustomerDO;
|
||||
import cn.iocoder.yudao.module.asset.dal.mysql.customer.CustomerMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.asset.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* 客户管理 Service 测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(CustomerServiceImpl.class)
|
||||
public class CustomerServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private CustomerServiceImpl customerService;
|
||||
|
||||
@Resource
|
||||
private CustomerMapper customerMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateCustomer_success() {
|
||||
// 准备参数
|
||||
CustomerSaveReqVO createReqVO = randomPojo(CustomerSaveReqVO.class, o -> {
|
||||
o.setCustomerName("测试客户");
|
||||
o.setCustomerType(0);
|
||||
o.setContactPhone("13800138000");
|
||||
o.setContactEmail("test@example.com");
|
||||
o.setIdCardNo("310101199001011234");
|
||||
o.setCreditLevel(1);
|
||||
o.setDepositAmount(new BigDecimal("5000.00"));
|
||||
o.setStatus(0);
|
||||
});
|
||||
|
||||
// 调用
|
||||
Long customerId = customerService.createCustomer(createReqVO);
|
||||
|
||||
// 断言
|
||||
assertNotNull(customerId);
|
||||
CustomerDO customer = customerMapper.selectById(customerId);
|
||||
assertNotNull(customer);
|
||||
assertEquals("测试客户", customer.getCustomerName());
|
||||
assertEquals(0, customer.getCustomerType());
|
||||
assertEquals("13800138000", customer.getContactPhone());
|
||||
assertNotNull(customer.getCustomerNo());
|
||||
assertTrue(customer.getCustomerNo().startsWith("CUST"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCustomer_success() {
|
||||
// mock 数据
|
||||
CustomerDO dbCustomer = new CustomerDO();
|
||||
dbCustomer.setCustomerNo("CUST000001");
|
||||
dbCustomer.setCustomerName("原客户名");
|
||||
dbCustomer.setCustomerType(0);
|
||||
dbCustomer.setContactPhone("13800138000");
|
||||
dbCustomer.setCreditLevel(1);
|
||||
dbCustomer.setDepositAmount(new BigDecimal("5000.00"));
|
||||
dbCustomer.setStatus(0);
|
||||
customerMapper.insert(dbCustomer);
|
||||
|
||||
// 准备参数
|
||||
CustomerSaveReqVO updateReqVO = new CustomerSaveReqVO();
|
||||
updateReqVO.setId(dbCustomer.getId());
|
||||
updateReqVO.setCustomerName("新客户名");
|
||||
updateReqVO.setCustomerType(0);
|
||||
updateReqVO.setContactPhone("13900139000");
|
||||
updateReqVO.setCreditLevel(2);
|
||||
updateReqVO.setDepositAmount(new BigDecimal("8000.00"));
|
||||
updateReqVO.setStatus(0);
|
||||
|
||||
// 调用
|
||||
customerService.updateCustomer(updateReqVO);
|
||||
|
||||
// 断言
|
||||
CustomerDO customer = customerMapper.selectById(updateReqVO.getId());
|
||||
assertEquals("新客户名", customer.getCustomerName());
|
||||
assertEquals("13900139000", customer.getContactPhone());
|
||||
assertEquals(2, customer.getCreditLevel());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateCustomer_notExists() {
|
||||
// 准备参数
|
||||
CustomerSaveReqVO updateReqVO = randomPojo(CustomerSaveReqVO.class, o -> {
|
||||
o.setId(999999L);
|
||||
o.setCustomerName("不存在的客户");
|
||||
o.setCustomerType(0);
|
||||
o.setStatus(0);
|
||||
});
|
||||
|
||||
// 调用并断言异常
|
||||
assertServiceException(() -> customerService.updateCustomer(updateReqVO), CUSTOMER_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCustomer_success() {
|
||||
// mock 数据
|
||||
CustomerDO dbCustomer = new CustomerDO();
|
||||
dbCustomer.setCustomerNo("CUST000001");
|
||||
dbCustomer.setCustomerName("测试客户");
|
||||
dbCustomer.setCustomerType(0);
|
||||
dbCustomer.setCreditLevel(1);
|
||||
dbCustomer.setDepositAmount(new BigDecimal("5000.00"));
|
||||
dbCustomer.setStatus(0);
|
||||
customerMapper.insert(dbCustomer);
|
||||
|
||||
// 调用
|
||||
customerService.deleteCustomer(dbCustomer.getId());
|
||||
|
||||
// 断言
|
||||
assertNull(customerMapper.selectById(dbCustomer.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCustomer_notExists() {
|
||||
// 调用并断言异常
|
||||
assertServiceException(() -> customerService.deleteCustomer(999999L), CUSTOMER_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCustomer() {
|
||||
// mock 数据
|
||||
CustomerDO dbCustomer = new CustomerDO();
|
||||
dbCustomer.setCustomerNo("CUST000001");
|
||||
dbCustomer.setCustomerName("测试客户");
|
||||
dbCustomer.setCustomerType(0);
|
||||
dbCustomer.setCreditLevel(1);
|
||||
dbCustomer.setDepositAmount(new BigDecimal("5000.00"));
|
||||
dbCustomer.setStatus(0);
|
||||
customerMapper.insert(dbCustomer);
|
||||
|
||||
// 调用
|
||||
CustomerDO customer = customerService.getCustomer(dbCustomer.getId());
|
||||
|
||||
// 断言
|
||||
assertNotNull(customer);
|
||||
assertEquals("测试客户", customer.getCustomerName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCustomerPage() {
|
||||
// mock 数据
|
||||
CustomerDO dbCustomer1 = new CustomerDO();
|
||||
dbCustomer1.setCustomerNo("CUST000001");
|
||||
dbCustomer1.setCustomerName("张三");
|
||||
dbCustomer1.setCustomerType(0);
|
||||
dbCustomer1.setContactPhone("13800138001");
|
||||
dbCustomer1.setCreditLevel(1);
|
||||
dbCustomer1.setDepositAmount(new BigDecimal("5000.00"));
|
||||
dbCustomer1.setStatus(0);
|
||||
customerMapper.insert(dbCustomer1);
|
||||
|
||||
CustomerDO dbCustomer2 = new CustomerDO();
|
||||
dbCustomer2.setCustomerNo("CUST000002");
|
||||
dbCustomer2.setCustomerName("李四");
|
||||
dbCustomer2.setCustomerType(1);
|
||||
dbCustomer2.setContactPhone("13800138002");
|
||||
dbCustomer2.setCreditLevel(1);
|
||||
dbCustomer2.setDepositAmount(new BigDecimal("5000.00"));
|
||||
dbCustomer2.setStatus(0);
|
||||
customerMapper.insert(dbCustomer2);
|
||||
|
||||
CustomerDO dbCustomer3 = new CustomerDO();
|
||||
dbCustomer3.setCustomerNo("CUST000003");
|
||||
dbCustomer3.setCustomerName("王五");
|
||||
dbCustomer3.setCustomerType(0);
|
||||
dbCustomer3.setContactPhone("13800138003");
|
||||
dbCustomer3.setCreditLevel(1);
|
||||
dbCustomer3.setDepositAmount(new BigDecimal("5000.00"));
|
||||
dbCustomer3.setStatus(1);
|
||||
customerMapper.insert(dbCustomer3);
|
||||
|
||||
// 测试 customerName 模糊查询
|
||||
CustomerPageReqVO reqVO = new CustomerPageReqVO();
|
||||
reqVO.setCustomerName("张");
|
||||
reqVO.setPageNo(1);
|
||||
reqVO.setPageSize(10);
|
||||
|
||||
PageResult<CustomerDO> pageResult = customerService.getCustomerPage(reqVO);
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals("张三", pageResult.getList().get(0).getCustomerName());
|
||||
|
||||
// 测试 customerType 筛选
|
||||
reqVO = new CustomerPageReqVO();
|
||||
reqVO.setCustomerType(1);
|
||||
reqVO.setPageNo(1);
|
||||
reqVO.setPageSize(10);
|
||||
|
||||
pageResult = customerService.getCustomerPage(reqVO);
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals("李四", pageResult.getList().get(0).getCustomerName());
|
||||
|
||||
// 测试 status 筛选
|
||||
reqVO = new CustomerPageReqVO();
|
||||
reqVO.setStatus(1);
|
||||
reqVO.setPageNo(1);
|
||||
reqVO.setPageSize(10);
|
||||
|
||||
pageResult = customerService.getCustomerPage(reqVO);
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals("王五", pageResult.getList().get(0).getCustomerName());
|
||||
|
||||
// 测试 contactPhone 模糊查询
|
||||
reqVO = new CustomerPageReqVO();
|
||||
reqVO.setContactPhone("138001");
|
||||
reqVO.setPageNo(1);
|
||||
reqVO.setPageSize(10);
|
||||
|
||||
pageResult = customerService.getCustomerPage(reqVO);
|
||||
assertEquals(3, pageResult.getTotal());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
spring:
|
||||
application:
|
||||
name: asset-server-test
|
||||
sql:
|
||||
init:
|
||||
mode: always
|
||||
schema-locations: classpath:sql/create_tables.sql
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
enabled: false
|
||||
config:
|
||||
enabled: false
|
||||
|
||||
yudao:
|
||||
info:
|
||||
version: 1.0.0-test
|
||||
base-package: cn.iocoder.yudao.module.asset
|
||||
web:
|
||||
admin-api:
|
||||
prefix: /admin-api
|
||||
controller: '**.controller.admin.**'
|
||||
security:
|
||||
permit-all-urls:
|
||||
- /admin-api/asset/**
|
||||
@@ -0,0 +1,2 @@
|
||||
-- 清理测试数据
|
||||
DELETE FROM asset_customer;
|
||||
@@ -0,0 +1,30 @@
|
||||
-- 客户信息表
|
||||
CREATE TABLE IF NOT EXISTS asset_customer (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
customer_no VARCHAR(50) NOT NULL,
|
||||
customer_name VARCHAR(100) NOT NULL,
|
||||
customer_type TINYINT NOT NULL DEFAULT 0,
|
||||
contact_person VARCHAR(50),
|
||||
contact_phone VARCHAR(20),
|
||||
contact_email VARCHAR(100),
|
||||
contact_address VARCHAR(255),
|
||||
id_card_no VARCHAR(18),
|
||||
id_card_front_url VARCHAR(255),
|
||||
id_card_back_url VARCHAR(255),
|
||||
driver_license_no VARCHAR(50),
|
||||
driver_license_url VARCHAR(255),
|
||||
company_name VARCHAR(200),
|
||||
unified_social_credit_code VARCHAR(50),
|
||||
business_license_url VARCHAR(255),
|
||||
legal_person VARCHAR(50),
|
||||
credit_level TINYINT DEFAULT 0,
|
||||
deposit_amount DECIMAL(10,2) DEFAULT 0.00,
|
||||
remark VARCHAR(500),
|
||||
status TINYINT NOT NULL DEFAULT 0,
|
||||
creator VARCHAR(64) DEFAULT '',
|
||||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updater VARCHAR(64) DEFAULT '',
|
||||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted TINYINT NOT NULL DEFAULT 0,
|
||||
tenant_id BIGINT NOT NULL DEFAULT 0
|
||||
);
|
||||
Reference in New Issue
Block a user