ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/AssetAdController.java
@@ -1,19 +1,35 @@ package com.ruoyi.web.controller.api; import com.baomidou.mybatisplus.core.metadata.IPage; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.system.dto.asset.AssetAdDTO; import com.ruoyi.system.dto.asset.AssetAdRentalRecordDTO; import com.ruoyi.system.model.AssetAdRentalRecord; import com.ruoyi.system.query.AssetAdQuery; import com.ruoyi.system.service.AssetAdRentalRecordService; import com.ruoyi.system.service.AssetAdService; import com.ruoyi.system.vo.asset.AssetAdDetailVO; import com.ruoyi.system.vo.asset.AssetAdVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.validation.Valid; @@ -34,21 +50,70 @@ public class AssetAdController { private final AssetAdService assetAdService; private final AssetAdRentalRecordService assetAdRentalRecordService; @PostMapping("/add") @ApiOperation(value = "新增广告无形资产") @Log(title = "新增广告无形资产", businessType = BusinessType.INSERT) @PostMapping("/add") public R<?> addAssetAd(@Valid @RequestBody AssetAdDTO dto) { assetAdService.addAssetAd(dto); return R.ok(); } @ApiOperation(value = "编辑广告无形资产") @Log(title = "编辑广告无形资产", businessType = BusinessType.UPDATE) @PostMapping("/edit") @ApiOperation(value = "新增广告无形资产") public R<?> editAssetAd(@Valid @RequestBody AssetAdDTO dto) { assetAdService.editAssetAd(dto); return R.ok(); } @ApiOperation("获取分页列表") @PostMapping("/page") public R<IPage<AssetAdVO>> getPageList(@RequestBody AssetAdQuery query) { return R.ok(assetAdService.getPageList(query)); } @ApiOperation("详情") @GetMapping("/detail/{id}") public R<AssetAdDetailVO> getDetail(@ApiParam(name = "id", value = "广告无形资产ID") @PathVariable Integer id) { return R.ok(assetAdService.getDetail(id)); } @ApiOperation("导入") @Log(title = "导入广告无形资产", businessType = BusinessType.IMPORT) @PostMapping("/import") public R<?> importAssetAd(@RequestPart("file") MultipartFile file){ //TODO 待完成 return R.ok(); } @ApiOperation("删除") @Transactional(rollbackFor = Exception.class) @DeleteMapping("/{id}") public R<?> delete(@ApiParam(name = "id", value = "广告无形资产ID") @PathVariable Integer id) { assetAdService.removeById(id); assetAdRentalRecordService.lambdaUpdate().eq(AssetAdRentalRecord::getAssetAdId, id).remove(); return R.ok(); } @ApiOperation("添加出租记录") @PostMapping("/rental/add") public R<?> addRentalRecord(@Valid @RequestBody AssetAdRentalRecordDTO dto){ assetAdRentalRecordService.addRentalRecord(dto); return R.ok(); } @ApiOperation("编辑出租记录") @PostMapping("/rental/edit") public R<?> editRentalRecord(@Valid @RequestBody AssetAdRentalRecordDTO dto){ assetAdRentalRecordService.editRentalRecord(dto); return R.ok(); } @ApiOperation("删除出租记录") @DeleteMapping("/rental/delete/{id}") public R<?> deleteRentalRecord(@ApiParam(name = "id", value = "广告无形资产ID") @PathVariable Integer id){ assetAdRentalRecordService.removeById(id); return R.ok(); } } ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/DrDisplacementController.java
@@ -2,10 +2,6 @@ import org.springframework.web.bind.annotation.RequestMapping; <<<<<<< HEAD ======= >>>>>>> origin/master import org.springframework.web.bind.annotation.RestController; /** @@ -13,11 +9,7 @@ * 拆迁情况 前端控制器 * </p> * <<<<<<< HEAD * @author mitao ======= * @author WuGuanFengYue >>>>>>> origin/master * @since 2025-10-17 */ @RestController @@ -25,7 +17,3 @@ public class DrDisplacementController { } <<<<<<< HEAD ======= >>>>>>> origin/master ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/AssetAdRentalRecordDTO.java
New file @@ -0,0 +1,58 @@ package com.ruoyi.system.dto.asset; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.math.BigDecimal; import java.time.LocalDate; /** * @author mitao * @date 2025/10/17 */ @Data @ApiModel("广告无形资产租赁记录数据传输对象") public class AssetAdRentalRecordDTO { @ApiModelProperty(value = "主键") private Integer id; @ApiModelProperty(value = "广告无形资产ID,关联asset_ad表") @NotNull(message = "广告无形资产ID不能为空") private Integer assetAdId; @ApiModelProperty(value = "使用人") @NotBlank(message = "使用人不能为空") private String useBy; @ApiModelProperty(value = "提醒人") @NotBlank(message = "提醒人不能为空") private String remindUser; @ApiModelProperty(value = "开始时间") @NotNull(message = "开始时间不能为空") private LocalDate startDate; @ApiModelProperty(value = "结束时间") @NotNull(message = "结束时间不能为空") private LocalDate endDate; @ApiModelProperty(value = "价格(租金)") @NotNull(message = "价格不能为空") private BigDecimal rentalPrice; @ApiModelProperty(value = "备注") private String remarks; @ApiModelProperty(value = "提醒时间(到期前多少天提醒,多个用分号分隔,如:30;15;7)") private String reminderDays; @ApiModelProperty(value = "提醒日期列表(自动计算,多个日期用分号分隔)") private String reminderDates; @ApiModelProperty(value = "附件URL列表(多个附件使用英文逗号拼接)") private String attachmentUrls; } ruoyi-system/src/main/java/com/ruoyi/system/model/AssetAdRentalRecord.java
@@ -35,9 +35,17 @@ @TableId(value = "id", type = IdType.AUTO) private Integer id; @ApiModelProperty(value = "广告无形资产ID,关联asset_advertisement表") @TableField("asset_advertisement_id") private Integer assetAdvertisementId; @ApiModelProperty(value = "广告无形资产ID,关联asset_ad表") @TableField("asset_ad_id") private Integer assetAdId; @ApiModelProperty(value = "使用人") @TableField("use_by") private String useBy; @ApiModelProperty(value = "提醒人") @TableField("remind_user") private String remindUser; @ApiModelProperty(value = "开始时间") @TableField("start_date") ruoyi-system/src/main/java/com/ruoyi/system/query/AssetAdQuery.java
New file @@ -0,0 +1,21 @@ package com.ruoyi.system.query; import com.ruoyi.common.core.domain.BasePage; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; /** * @author mitao * @date 2025/10/17 */ @EqualsAndHashCode(callSuper = true) @Data @ApiModel("广告无形资产查询条件对象") public class AssetAdQuery extends BasePage { private static final long serialVersionUID = -7429250301941138611L; @ApiModelProperty("关键字 资产名称/资产编号") private String keyword; } ruoyi-system/src/main/java/com/ruoyi/system/service/AssetAdRentalRecordService.java
@@ -1,6 +1,7 @@ package com.ruoyi.system.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.system.dto.asset.AssetAdRentalRecordDTO; import com.ruoyi.system.model.AssetAdRentalRecord; /** @@ -13,4 +14,7 @@ */ public interface AssetAdRentalRecordService extends IService<AssetAdRentalRecord> { void addRentalRecord(AssetAdRentalRecordDTO dto); void editRentalRecord(AssetAdRentalRecordDTO dto); } ruoyi-system/src/main/java/com/ruoyi/system/service/AssetAdService.java
@@ -1,8 +1,12 @@ package com.ruoyi.system.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.system.dto.asset.AssetAdDTO; import com.ruoyi.system.model.AssetAd; import com.ruoyi.system.query.AssetAdQuery; import com.ruoyi.system.vo.asset.AssetAdDetailVO; import com.ruoyi.system.vo.asset.AssetAdVO; /** * <p> @@ -24,4 +28,13 @@ * @param dto */ void editAssetAd(AssetAdDTO dto); /** * 无形资产分页列表 * @param query * @return */ IPage<AssetAdVO> getPageList(AssetAdQuery query); AssetAdDetailVO getDetail(Integer id); } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetAdRentalRecordServiceImpl.java
@@ -1,10 +1,15 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.system.dto.asset.AssetAdRentalRecordDTO; import com.ruoyi.system.mapper.AssetAdRentalRecordMapper; import com.ruoyi.system.model.AssetAdRentalRecord; import com.ruoyi.system.service.AssetAdRentalRecordService; import org.springframework.stereotype.Service; import java.util.Objects; /** * <p> @@ -16,5 +21,18 @@ */ @Service public class AssetAdRentalRecordServiceImpl extends ServiceImpl<AssetAdRentalRecordMapper, AssetAdRentalRecord> implements AssetAdRentalRecordService { @Override public void addRentalRecord(AssetAdRentalRecordDTO dto) { AssetAdRentalRecord assetAdRentalRecord = BeanUtil.copyProperties(dto, AssetAdRentalRecord.class); save(assetAdRentalRecord); } @Override public void editRentalRecord(AssetAdRentalRecordDTO dto) { if (Objects.isNull(dto.getId())) { throw new ServiceException("租赁记录ID不能为空"); } AssetAdRentalRecord assetAdRentalRecord = BeanUtil.copyProperties(dto, AssetAdRentalRecord.class); updateById(assetAdRentalRecord); } } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetAdServiceImpl.java
@@ -1,19 +1,35 @@ package com.ruoyi.system.service.impl; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.system.dto.asset.AssetAdDTO; import com.ruoyi.system.mapper.AssetAdMapper; import com.ruoyi.system.mapper.AssetAdRentalRecordMapper; import com.ruoyi.system.model.AssetAd; import com.ruoyi.system.model.AssetAdRentalRecord; import com.ruoyi.system.query.AssetAdQuery; import com.ruoyi.system.service.AssetAdService; import com.ruoyi.system.service.AssetTypeService; import com.ruoyi.system.vo.asset.AssetAdDetailVO; import com.ruoyi.system.vo.asset.AssetAdRentalRecordVO; import com.ruoyi.system.vo.asset.AssetAdVO; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; /** * <p> @@ -27,6 +43,8 @@ @RequiredArgsConstructor(onConstructor_ = {@Lazy}) public class AssetAdServiceImpl extends ServiceImpl<AssetAdMapper, AssetAd> implements AssetAdService { private final AssetTypeService assetTypeService; private final AssetAdRentalRecordMapper rentalRecordMapper; @Override public void addAssetAd(AssetAdDTO dto) { AssetAd assetAd = BeanUtil.copyProperties(dto, AssetAd.class); @@ -62,4 +80,105 @@ assetAd.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName()); updateById(assetAd); } @Override public IPage<AssetAdVO> getPageList(AssetAdQuery query) { // 1. 分页查询 AssetAd Page<AssetAd> page = new Page<>(query.getPageNum(), query.getPageSize()); LambdaQueryWrapper<AssetAd> queryWrapper = new LambdaQueryWrapper<AssetAd>() .like(StringUtils.isNotBlank(query.getKeyword()), AssetAd::getAssetName, query.getKeyword()) .or() .like(StringUtils.isNotBlank(query.getKeyword()), AssetAd::getAssetCode, query.getKeyword()) .orderByDesc(AssetAd::getCreateTime); Page<AssetAd> assetPage = this.page(page, queryWrapper); // 2. 如果没有数据,返回空分页 if (assetPage.getRecords().isEmpty()) { return new Page<>(query.getPageNum(), query.getPageSize()); } // 3. 获取所有资产ID List<Integer> assetAdIds = assetPage.getRecords().stream() .map(AssetAd::getId) .collect(Collectors.toList()); // 4. 查询相关租赁记录 LocalDate today = LocalDate.now(); List<AssetAdRentalRecord> allRentalRecords = rentalRecordMapper.selectList( new LambdaQueryWrapper<AssetAdRentalRecord>() .in(AssetAdRentalRecord::getAssetAdId, assetAdIds) .ge(AssetAdRentalRecord::getStartDate, today) .le(AssetAdRentalRecord::getEndDate,today) .orderByDesc(AssetAdRentalRecord::getCreateTime) ); // 5. 转换为Map Map<Integer, AssetAdRentalRecord> currentRentalMap = allRentalRecords.stream() .collect(Collectors.toMap(AssetAdRentalRecord::getAssetAdId, Function.identity())); // 6. 组装VO数据 List<AssetAdVO> voList = new ArrayList<>(); for (AssetAd asset : assetPage.getRecords()) { AssetAdVO vo = BeanUtil.copyProperties(asset, AssetAdVO.class); // 设置租赁相关信息 AssetAdRentalRecord currentRental = currentRentalMap.get(asset.getId()); if (currentRental != null) { vo.setCurrentUseBy(currentRental.getUseBy()); vo.setRentalPrice(currentRental.getRentalPrice()); vo.setUseDuration(calculateUseDuration(currentRental.getStartDate(), currentRental.getEndDate())); } voList.add(vo); } // 7. 返回分页结果 Page<AssetAdVO> resultPage = new Page<>(query.getPageNum(), query.getPageSize()); resultPage.setRecords(voList); resultPage.setTotal(assetPage.getTotal()); resultPage.setSize(assetPage.getSize()); resultPage.setCurrent(assetPage.getCurrent()); resultPage.setPages(assetPage.getPages()); return resultPage; } /** * 计算使用期限(月) */ private Integer calculateUseDuration(LocalDate startDate, LocalDate endDate) { if (startDate == null || endDate == null) { return null; } // 计算月份差值 long months = ChronoUnit.MONTHS.between(startDate, endDate); return (int) months; } @Override public AssetAdDetailVO getDetail(Integer id) { // 1. 查询资产基础信息 AssetAd assetAd = getById(id); if (assetAd == null) { return null; } // 2. 查询租赁记录 List<AssetAdRentalRecord> rentalRecords = rentalRecordMapper.selectList( new LambdaQueryWrapper<AssetAdRentalRecord>() .eq(AssetAdRentalRecord::getAssetAdId, id) .orderByDesc(AssetAdRentalRecord::getStartDate) ); // 3. 转换为AssetAdDetailVO AssetAdDetailVO detailVO = BeanUtil.copyProperties(assetAd, AssetAdDetailVO.class); // 4. 转换租赁记录为VO列表 List<AssetAdRentalRecordVO> rentalRecordVOList = BeanUtil.copyToList(rentalRecords, AssetAdRentalRecordVO.class); detailVO.setRentalRecordVOList(rentalRecordVOList); return detailVO; } } ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/AssetAdDetailVO.java
New file @@ -0,0 +1,20 @@ package com.ruoyi.system.vo.asset; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.util.List; /** * @author mitao * @date 2025/10/17 */ @Data @EqualsAndHashCode(callSuper = true) @ApiModel("广告无形资产详情视图对象") public class AssetAdDetailVO extends AssetAdVO{ @ApiModelProperty("租赁记录") private List<AssetAdRentalRecordVO> rentalRecordVOList; } ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/AssetAdRentalRecordVO.java
New file @@ -0,0 +1,53 @@ package com.ruoyi.system.vo.asset; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDate; /** * @author mitao * @date 2025/10/17 */ @Data @ApiModel("广告无形资产租赁记录视图对象") public class AssetAdRentalRecordVO { @ApiModelProperty(value = "主键") private Integer id; @ApiModelProperty(value = "广告无形资产ID,关联asset_ad表") private Integer assetAdId; @ApiModelProperty(value = "使用人") private String useBy; @ApiModelProperty(value = "提醒人") private String remindUser; @ApiModelProperty(value = "开始时间") private LocalDate startDate; @ApiModelProperty(value = "结束时间") private LocalDate endDate; @ApiModelProperty(value = "价格(租金)") private BigDecimal rentalPrice; @ApiModelProperty(value = "备注") private String remarks; @ApiModelProperty(value = "提醒时间(到期前多少天提醒,多个用分号分隔,如:30;15;7)") private String reminderDays; @ApiModelProperty(value = "提醒日期列表(自动计算,多个日期用分号分隔)") private String reminderDates; @ApiModelProperty(value = "附件URL列表(多个附件使用英文逗号拼接)") private String attachmentUrls; @ApiModelProperty(value = "创建人") private String createBy; } ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/AssetAdVO.java
New file @@ -0,0 +1,56 @@ package com.ruoyi.system.vo.asset; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDateTime; /** * @author mitao * @date 2025/10/17 */ @Data @ApiModel("广告无形资产视图对象") public class AssetAdVO { @ApiModelProperty(value = "主键") private Integer id; @ApiModelProperty(value = "资产名称") private String assetName; @ApiModelProperty(value = "资产编号") private String assetCode; @ApiModelProperty(value = "位置") private String location; @ApiModelProperty(value = "租赁形式(长期租赁、一次性租赁等)") private String rentalType; @ApiModelProperty(value = "资产状态:0-闲置,1-出租,2-借用,3-占用,4-其他") private Integer assetStatus; @ApiModelProperty(value = "备注") private String remarks; @ApiModelProperty(value = "当前使用人") private String currentUseBy; @ApiModelProperty(value = "使用期限") private Integer useDuration; @ApiModelProperty(value = "价格") private BigDecimal rentalPrice; @ApiModelProperty(value = "附件URL列表(多个使用英文逗号拼接)") private String attachmentUrls; @ApiModelProperty(value = "创建时间") @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private LocalDateTime createTime; }