mitao
1 天以前 03587b58b343956f910a653c37b9a7bcd84e4af9
资产管理-资产领用列表
阿里云OSS文件上传
27个文件已修改
7个文件已添加
892 ■■■■ 已修改文件
pom.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/OaApprovalApplicationAssetController.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/OaApprovalApplicationStorageController.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/OaApprovalApplicationsController.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/FileUploadController.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-prod.yml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-test.yml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/OssConfig.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/controller/FileController.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/OaApprovalApplicationStorageDTO.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/OaApprovalApplicationStorageGeneralDTO.java 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/OaApprovalApplicationStoragePropertyDTO.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/OaApprovalApplicationStorageVehicleDTO.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/OaApprovalApplicationAssetMapper.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/AssetGeneralExt.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/AssetMain.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/AssetPropertyExt.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/OaApprovalApplicationAsset.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/OaApprovalApplications.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/query/OaApprovalApplicationAssetPageQuery.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/OaApprovalApplicationAssetService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/OssService.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OaApprovalApplicationAssetServiceImpl.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OaApprovalApplicationPurchaseServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OaApprovalApplicationStorageServiceImpl.java 117 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OssServiceImpl.java 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/OaApprovalApplicationAssetDetailVO.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/OaApprovalApplicationAssetPageVO.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/OaApprovalApplicationStorageGeneralDetailVO.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/OaApprovalApplicationStoragePropertyDetailVO.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/OaApprovalApplicationStorageVehicleDetailVO.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/OaApprovalApplicationAssetMapper.xml 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -30,6 +30,7 @@
        <poi.version>4.1.2</poi.version>
        <velocity.version>2.3</velocity.version>
        <jwt.version>0.9.1</jwt.version>
        <aliyun-oss.version>3.17.4</aliyun-oss.version>
    </properties>
    <!-- 依赖声明 -->
@@ -156,6 +157,12 @@
                <version>${ruoyi.version}</version>
            </dependency>
            <!--阿里云oss-->
            <dependency>
                <groupId>com.aliyun.oss</groupId>
                <artifactId>aliyun-sdk-oss</artifactId>
                <version>${aliyun-oss.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/OaApprovalApplicationAssetController.java
@@ -1,16 +1,23 @@
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.common.utils.SecurityUtils;
import com.ruoyi.system.dto.asset.OaApprovalApplicationAssetReceiveDTO;
import com.ruoyi.system.query.OaApprovalApplicationAssetPageQuery;
import com.ruoyi.system.service.OaApprovalApplicationAssetService;
import com.ruoyi.system.vo.asset.OaApprovalApplicationAssetPageVO;
import com.ruoyi.system.vo.asset.OaApprovalApplicationAssetDetailVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -38,5 +45,29 @@
        oaApprovalApplicationAssetService.submitReceive(dto);
        return R.ok();
    }
}
    @ApiOperation("获取资产领用申请分页列表")
    @PostMapping("/page-list")
    public R<IPage<OaApprovalApplicationAssetPageVO>> getReceivePageList(@RequestBody OaApprovalApplicationAssetPageQuery pageQuery) {
        // 数据权限:非管理员仅能查看本部门
        Long userId = SecurityUtils.getUserId();
        boolean isAdmin = SecurityUtils.isAdmin(userId);
        if (!isAdmin) {
            try {
                pageQuery.setDeptId(Integer.valueOf(SecurityUtils.getDeptId()));
            } catch (Exception e) {
                // ignore parse, leave null if cannot parse
            }
        }
        IPage<OaApprovalApplicationAssetPageVO> page = oaApprovalApplicationAssetService.getReceivePageList(pageQuery);
        return R.ok(page);
    }
    @ApiOperation("获取资产领用详情")
    @GetMapping("/detail/receive/{id}")
    public R<OaApprovalApplicationAssetDetailVO> getReceiveDetail(@PathVariable Integer id) {
        OaApprovalApplicationAssetDetailVO detail = oaApprovalApplicationAssetService.getDetail(id);
        return R.ok(detail);
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/OaApprovalApplicationStorageController.java
@@ -58,6 +58,16 @@
    @Log(title = "通用资产入库申请-提交", businessType = BusinessType.INSERT)
    public R<Void> submitGeneralAssetStorage(@Valid @RequestBody OaApprovalApplicationStorageGeneralDTO dto) {
        validateAddress(dto);
        // 校验每条明细的权属单位/部门名称是否存在
        for (OaApprovalApplicationStorageGeneralDTO.GeneralAssetItemDTO item : dto.getAssetItems()) {
            if (StringUtils.isEmpty(item.getOwnershipDeptName())) {
                throw new ServiceException("权属单位/部门名称不能为空");
            }
            TDept owner = deptService.lambdaQuery().eq(TDept::getDeptName, item.getOwnershipDeptName()).one();
            if (owner == null) {
                throw new ServiceException("权属单位/部门不存在: " + item.getOwnershipDeptName());
            }
        }
        oaApprovalApplicationStorageService.submitGeneralAssetStorage(dto);
        return R.ok();
    }
@@ -67,6 +77,15 @@
    @Log(title = "房产资产入库申请-提交", businessType = BusinessType.INSERT)
    public R<Void> submitPropertyAssetStorage(@Valid @RequestBody OaApprovalApplicationStoragePropertyDTO dto) {
        validateAddress(dto);
        for (OaApprovalApplicationStoragePropertyDTO.PropertyAssetItemDTO item : dto.getAssetItems()) {
            if (StringUtils.isEmpty(item.getOwnershipDeptName())) {
                throw new ServiceException("权属单位/部门名称不能为空");
            }
            TDept owner = deptService.lambdaQuery().eq(TDept::getDeptName, item.getOwnershipDeptName()).one();
            if (owner == null) {
                throw new ServiceException("权属单位/部门不存在: " + item.getOwnershipDeptName());
            }
        }
        oaApprovalApplicationStorageService.submitPropertyAssetStorage(dto);
        return R.ok();
    }
@@ -76,6 +95,15 @@
    @Log(title = "车辆资产入库申请-提交", businessType = BusinessType.INSERT)
    public R<Void> submitVehicleAssetStorage(@Valid @RequestBody OaApprovalApplicationStorageVehicleDTO dto) {
        validateAddress(dto);
        for (OaApprovalApplicationStorageVehicleDTO.VehicleAssetItemDTO item : dto.getAssetItems()) {
            if (StringUtils.isEmpty(item.getOwnershipDeptName())) {
                throw new ServiceException("权属单位/部门名称不能为空");
            }
            TDept owner = deptService.lambdaQuery().eq(TDept::getDeptName, item.getOwnershipDeptName()).one();
            if (owner == null) {
                throw new ServiceException("权属单位/部门不存在: " + item.getOwnershipDeptName());
            }
        }
        oaApprovalApplicationStorageService.submitVehicleAssetStorage(dto);
        return R.ok();
    }
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/OaApprovalApplicationsController.java
@@ -6,13 +6,31 @@
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.TDept;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.dto.*;
import com.ruoyi.system.emums.ApprovalFlowNodeEnum;
import com.ruoyi.system.dto.AddAdvertisementDTO;
import com.ruoyi.system.dto.AddBusinessTripDTO;
import com.ruoyi.system.dto.AddContactDTO;
import com.ruoyi.system.dto.AddContractDTO;
import com.ruoyi.system.dto.AddLeaveDTO;
import com.ruoyi.system.dto.AddLeaveDestroyDTO;
import com.ruoyi.system.dto.AddMoneyDTO;
import com.ruoyi.system.dto.AddOutDTO;
import com.ruoyi.system.dto.AddPaymentDTO;
import com.ruoyi.system.dto.AddReimbursementDTO;
import com.ruoyi.system.emums.ApprovalStatusEnum;
import com.ruoyi.system.emums.ApprovalTypeEnum;
import com.ruoyi.system.model.*;
import com.ruoyi.system.model.OaApprovalApplicationAdvertisement;
import com.ruoyi.system.model.OaApprovalApplicationAttendance;
import com.ruoyi.system.model.OaApprovalApplicationContact;
import com.ruoyi.system.model.OaApprovalApplicationContract;
import com.ruoyi.system.model.OaApprovalApplicationMoney;
import com.ruoyi.system.model.OaApprovalApplicationPayment;
import com.ruoyi.system.model.OaApprovalApplicationReimbursement;
import com.ruoyi.system.model.OaApprovalApplicationReimbursementItem;
import com.ruoyi.system.model.OaApprovalApplications;
import com.ruoyi.system.model.OaApprovalFlowNode;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.OaApprovalApplicationAdvertisementService;
import com.ruoyi.system.service.OaApprovalApplicationAttendanceService;
@@ -31,12 +49,11 @@
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import oshi.driver.mac.net.NetStat;
import javax.annotation.Resource;
import java.math.BigDecimal;
@@ -47,8 +64,6 @@
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import com.ruoyi.system.emums.ApprovalStatusEnum;
import com.ruoyi.common.exception.ServiceException;
/**
 * <p>
@@ -581,9 +596,9 @@
    }
    @Log(title = "审批-撤回通用审批单", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "撤回审批单:仅更新状态为已撤回")
    @ApiOperation(value = "撤回审批单(通用接口)")
    @PutMapping(value = "/withdraw/{id}")
    public R withdraw(@PathVariable Integer id) {
    public R<?> withdraw(@PathVariable Integer id) {
        OaApprovalApplications current = approvalApplicationsService.getById(id);
        if (current == null) {
            throw new ServiceException("审批单不存在");
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/FileUploadController.java
New file
@@ -0,0 +1,43 @@
package com.ruoyi.web.controller.system;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.service.OssService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
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 java.io.IOException;
/**
 * @author mitao
 * @date 2025/9/19
 */
@Api(tags = {"文件上传接口"})
@RestController
@RequestMapping("/file-upload/")
public class FileUploadController {
    @Autowired
    private OssService ossService;
    /**
     * 上传文件
     *
     * @param file
     * @return
     */
    @ApiOperation(value = "OSS文件上传")
    @PostMapping("/upload-oss")
    public R<String> upload(@RequestPart("file") MultipartFile file) {
        String fileUrl;
        try {
            fileUrl = ossService.uploadFile(file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return R.ok(fileUrl);
    }
}
ruoyi-admin/src/main/resources/application-prod.yml
@@ -220,3 +220,12 @@
    bucketAddr:
    rootSrc:
    location: /clean
# 阿里云对象存储
oss:
  accessKeyId: LTAI5tNW8B4CYP1WK7yS3bfW
  accessKeySecret: 9RrPDLd7wh4VGCjXxD8ULIdKiuY5Ly
  upload-endpoint: https://oss-cn-chengdu.aliyuncs.com
  download-endpoint: https://zhpt-oss.oss-cn-chengdu.aliyuncs.com
  bucketName: zhpt
  folder: shehongchengtou
ruoyi-admin/src/main/resources/application-test.yml
@@ -65,7 +65,7 @@
  devtools:
    restart:
      # 热部署开关
      enabled: true
      enabled: false
  # redis 配置
  redis:
    # 地址
@@ -221,6 +221,15 @@
    bucketAddr:
    rootSrc:
    location: /clean
# 阿里云对象存储
oss:
  accessKeyId: LTAI5tNW8B4CYP1WK7yS3bfW
  accessKeySecret: 9RrPDLd7wh4VGCjXxD8ULIdKiuY5Ly
  upload-endpoint: https://oss-cn-chengdu.aliyuncs.com
  download-endpoint: https://zhpt-oss.oss-cn-chengdu.aliyuncs.com
  bucketName: zhpt
  folder: shehongchengtou
sms:
  enable: true
  appId: 1400957506
ruoyi-common/pom.xml
@@ -210,6 +210,11 @@
            <artifactId>javax.mail</artifactId>
            <version>1.6.2</version> <!-- 请检查是否有更新的版本 -->
        </dependency>
        <!--阿里云oss-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-common/src/main/java/com/ruoyi/common/config/OssConfig.java
New file
@@ -0,0 +1,59 @@
package com.ruoyi.common.config;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
 * 存储-配置
 *
 * @author mitao
 */
@ConfigurationProperties(prefix = "oss")
@Component
@Slf4j
@Data
public class OssConfig {
    private String folder = "dev";
    private String accessKeyId;
    private String accessKeySecret;
    private String uploadEndpoint;
    private String downloadEndpoint;
    private String bucketName;
    public static String FOLDER;
    public static String ACCESS_KEY_ID;
    public static String ACCESS_KEY_SECRET;
    public static String UPLOAD_ENDPOINT;
    public static String DOWNLOAD_ENDPOINT;
    public static String BUCKET_NAME;
    @PostConstruct
    public void init() {
        log.debug("OSS配置信息:" + JSONObject.toJSONString(this));
        FOLDER = folder;
        ACCESS_KEY_ID = accessKeyId;
        ACCESS_KEY_SECRET = accessKeySecret;
        UPLOAD_ENDPOINT = uploadEndpoint;
        DOWNLOAD_ENDPOINT = downloadEndpoint;
        BUCKET_NAME = bucketName;
    }
    public String getStoreFolder() {
        return getFolder();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/controller/FileController.java
@@ -5,10 +5,13 @@
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/OaApprovalApplicationStorageDTO.java
@@ -36,11 +36,6 @@
    @NotBlank(message = "申请人姓名不能为空")
    private String applicantName;
    @ApiModelProperty(value = "申请日期")
    @NotNull(message = "申请日期不能为空")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate applicationDate;
    @ApiModelProperty(value = "入库备注")
    @Size(max = 500, message = "入库备注不能超过500字符")
    private String applicationReason;
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/OaApprovalApplicationStorageGeneralDTO.java
@@ -42,6 +42,10 @@
        @NotBlank(message = "资产名称不能为空")
        private String assetName;
        @ApiModelProperty(value = "类别")
        @NotBlank(message = "类别不能为空")
        private String category;
        @ApiModelProperty(value = "规格型号")
        private String specificationModel;
@@ -60,13 +64,16 @@
        @ApiModelProperty(value = "使用年限(年)")
        private Integer usefulLife;
        @ApiModelProperty(value = "权属单位/部门ID")
        private Integer ownershipDeptId;
        @ApiModelProperty(value = "总金额")
        private BigDecimal totalValue;
        @ApiModelProperty(value = "权属单位/部门名称")
        private String ownershipDeptName;
        @ApiModelProperty(value = "使用人")
        private String userName;
        @ApiModelProperty(value = "位置类型 0-部门,1-仓库,2-录入地址")
        @ApiModelProperty(value = "使用/位置类型 0-部门,1-仓库,2-录入地址")
        private Integer addressType;
        @ApiModelProperty(value = "使用部门/位置名称")
@@ -99,40 +106,5 @@
        @ApiModelProperty(value = "入账金额")
        private BigDecimal accountingAmount;
        // 通用资产扩展表字段
        @ApiModelProperty(value = "供应商名称")
        private String supplierName;
        @ApiModelProperty(value = "采购日期")
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private LocalDate purchaseDate;
        @ApiModelProperty(value = "保修期(月)")
        private Integer warrantyPeriod;
        @ApiModelProperty(value = "保修到期日期")
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private LocalDate warrantyExpireDate;
        @ApiModelProperty(value = "折旧方法")
        private String depreciationMethod;
        @ApiModelProperty(value = "折旧率")
        private BigDecimal depreciationRate;
        @ApiModelProperty(value = "净值")
        private BigDecimal netValue;
        @ApiModelProperty(value = "维护周期(月)")
        private Integer maintenanceCycle;
        @ApiModelProperty(value = "上次维护日期")
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private LocalDate lastMaintenanceDate;
        @ApiModelProperty(value = "下次维护日期")
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private LocalDate nextMaintenanceDate;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/OaApprovalApplicationStoragePropertyDTO.java
@@ -42,6 +42,10 @@
        @NotBlank(message = "资产名称不能为空")
        private String assetName;
        @ApiModelProperty(value = "类别")
        @NotBlank(message = "类别不能为空")
        private String category;
        @ApiModelProperty(value = "规格型号")
        private String specificationModel;
@@ -60,13 +64,13 @@
        @ApiModelProperty(value = "使用年限(年)")
        private Integer usefulLife;
        @ApiModelProperty(value = "权属单位/部门ID")
        private Integer ownershipDeptId;
        @ApiModelProperty(value = "权属单位/部门名称")
        private String ownershipDeptName;
        @ApiModelProperty(value = "使用人")
        private String userName;
        @ApiModelProperty(value = "位置类型 0-部门,1-仓库,2-录入地址")
        @ApiModelProperty(value = "使用/位置类型 0-部门,1-仓库,2-录入地址")
        private Integer addressType;
        @ApiModelProperty(value = "使用部门/位置名称")
@@ -136,7 +140,7 @@
        private String resettlementSituation;
        @ApiModelProperty(value = "是否抵押:0-否,1-是")
        private Boolean isMortgaged;
        private Integer mortgaged;
        @ApiModelProperty(value = "承租方")
        private String tenantName;
ruoyi-system/src/main/java/com/ruoyi/system/dto/asset/OaApprovalApplicationStorageVehicleDTO.java
@@ -42,6 +42,10 @@
        @NotBlank(message = "资产名称不能为空")
        private String assetName;
        @ApiModelProperty(value = "类别")
        @NotBlank(message = "类别不能为空")
        private String category;
        @ApiModelProperty(value = "规格型号")
        private String specificationModel;
@@ -60,13 +64,13 @@
        @ApiModelProperty(value = "使用年限(年)")
        private Integer usefulLife;
        @ApiModelProperty(value = "权属单位/部门ID")
        private Integer ownershipDeptId;
        @ApiModelProperty(value = "权属单位/部门名称")
        private String ownershipDeptName;
        @ApiModelProperty(value = "使用人")
        private String userName;
        @ApiModelProperty(value = "位置类型 0-部门,1-仓库,2-录入地址")
        @ApiModelProperty(value = "使用/位置类型 0-部门,1-仓库,2-录入地址")
        private Integer addressType;
        @ApiModelProperty(value = "使用部门/位置名称")
ruoyi-system/src/main/java/com/ruoyi/system/mapper/OaApprovalApplicationAssetMapper.java
@@ -1,7 +1,12 @@
package com.ruoyi.system.mapper;
import com.ruoyi.system.model.OaApprovalApplicationAsset;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.system.model.OaApprovalApplicationAsset;
import com.ruoyi.system.query.OaApprovalApplicationAssetPageQuery;
import com.ruoyi.system.vo.asset.OaApprovalApplicationAssetPageVO;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
@@ -13,4 +18,6 @@
 */
public interface OaApprovalApplicationAssetMapper extends BaseMapper<OaApprovalApplicationAsset> {
    IPage<OaApprovalApplicationAssetPageVO> selectReceivePage(Page<OaApprovalApplicationAssetPageVO> page,
                                                             @Param("query") OaApprovalApplicationAssetPageQuery query);
}
ruoyi-system/src/main/java/com/ruoyi/system/model/AssetGeneralExt.java
@@ -18,7 +18,7 @@
 * <p>
 * 通用资产扩展表
 * </p>
 *
 * 已弃用
 * @author WuGuanFengYue
 * @since 2025-09-15
 */
ruoyi-system/src/main/java/com/ruoyi/system/model/AssetMain.java
@@ -54,6 +54,10 @@
    @TableField("specification_model")
    private String specificationModel;
    @ApiModelProperty(value = "类别")
    @TableField("category")
    private String category;
    @ApiModelProperty(value = "资产类别ID,关联asset_type表")
    @TableField("asset_type_id")
    private Integer assetTypeId;
ruoyi-system/src/main/java/com/ruoyi/system/model/AssetPropertyExt.java
@@ -84,7 +84,7 @@
    @ApiModelProperty(value = "是否抵押:0-否,1-是")
    @TableField("is_mortgaged")
    private Boolean isMortgaged;
    private Integer mortgaged;
    @ApiModelProperty(value = "承租方")
    @TableField("tenant_name")
ruoyi-system/src/main/java/com/ruoyi/system/model/OaApprovalApplicationAsset.java
@@ -54,7 +54,7 @@
    @ApiModelProperty(value = "操作类型 0-领用,1-借用,2-归还")
    @TableField("type")
    private Boolean type;
    private Integer type;
    @ApiModelProperty(value = "借用审批ID,类型为归还时使用。")
    @TableField("borrow_application_id")
ruoyi-system/src/main/java/com/ruoyi/system/model/OaApprovalApplications.java
@@ -48,14 +48,14 @@
    @ApiModelProperty(value = "申请人")
    @TableField("applicant_name")
    private String applicantName;
    @ApiModelProperty(value = "所属部门")
    @TableField("dept_name")
    private String deptName;
    @ApiModelProperty(value = "部门ID")
    @TableField("dept_id")
    private Integer deptId;
    @ApiModelProperty(value = "申请日期")
    @TableField("application_date")
ruoyi-system/src/main/java/com/ruoyi/system/query/OaApprovalApplicationAssetPageQuery.java
New file
@@ -0,0 +1,24 @@
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;
/**
 * 资产领用申请分页查询对象
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("资产领用申请分页查询对象")
public class OaApprovalApplicationAssetPageQuery extends BasePage {
    private static final long serialVersionUID = 5202319182345234524L;
    @ApiModelProperty("关键词(标题/单据号/部门/领用人)")
    private String keyword;
    @ApiModelProperty("部门ID(非管理员时作为数据权限过滤)")
    private Integer deptId;
}
ruoyi-system/src/main/java/com/ruoyi/system/service/OaApprovalApplicationAssetService.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.model.OaApprovalApplicationAsset;
import com.ruoyi.system.dto.asset.OaApprovalApplicationAssetReceiveDTO;
import com.ruoyi.system.query.OaApprovalApplicationAssetPageQuery;
import com.ruoyi.system.vo.asset.OaApprovalApplicationAssetPageVO;
import com.ruoyi.system.vo.asset.OaApprovalApplicationAssetDetailVO;
/**
 * <p>
@@ -19,4 +23,15 @@
     * @param dto 领用申请DTO
     */
    void submitReceive(OaApprovalApplicationAssetReceiveDTO dto);
    /**
     * 获取资产领用申请分页列表
     */
    IPage<OaApprovalApplicationAssetPageVO> getReceivePageList(OaApprovalApplicationAssetPageQuery pageQuery);
    /**
     * 获取资产领用/借用/归还详情
     * @param id 领用/借用/归还明细表ID(oa_approval_application_asset.id)
     */
    OaApprovalApplicationAssetDetailVO getDetail(Integer id);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/OssService.java
New file
@@ -0,0 +1,28 @@
package com.ruoyi.system.service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
 * @author mitao
 * @date 2024/12/23
 */
public interface OssService {
    /**
     * 文件上传
     *
     * @param file
     * @return
     */
    String uploadFile(MultipartFile file) throws IOException;
    /**
     * 文件上传,指定上传路径
     *
     * @param storagePath
     * @param file
     * @return
     */
    String upload(String storagePath, MultipartFile file) throws IOException;
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OaApprovalApplicationAssetServiceImpl.java
@@ -1,5 +1,7 @@
package com.ruoyi.system.service.impl;
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.exception.ServiceException;
import com.ruoyi.system.dto.asset.OaApprovalApplicationAssetReceiveDTO;
@@ -10,11 +12,14 @@
import com.ruoyi.system.model.OaApprovalApplicationAssetItem;
import com.ruoyi.system.model.OaApprovalApplications;
import com.ruoyi.system.model.OaApprovalFlowNode;
import com.ruoyi.system.query.OaApprovalApplicationAssetPageQuery;
import com.ruoyi.system.service.OaApprovalApplicationAssetItemService;
import com.ruoyi.system.service.OaApprovalApplicationAssetService;
import com.ruoyi.system.service.OaApprovalApplicationsService;
import com.ruoyi.system.service.OaApprovalFlowNodeService;
import com.ruoyi.system.service.OaApprovalTodoService;
import com.ruoyi.system.vo.asset.OaApprovalApplicationAssetPageVO;
import com.ruoyi.system.vo.asset.OaApprovalApplicationAssetDetailVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -111,7 +116,7 @@
        asset.setAssetTypeId(dto.getAssetTypeId());
        asset.setOperateTime(dto.getOperateTime());
        asset.setExpectReturnDate(dto.getExpectReturnDate());
        asset.setType(Boolean.FALSE); // 0-领用
        asset.setType(0); // 0-领用
        return asset;
    }
@@ -130,4 +135,29 @@
        String sequenceStr = String.format("%03d", sequence);
        return prefix + sequenceStr;
    }
    @Override
    public IPage<OaApprovalApplicationAssetPageVO> getReceivePageList(OaApprovalApplicationAssetPageQuery pageQuery) {
        Page<OaApprovalApplicationAssetPageVO> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
        return this.baseMapper.selectReceivePage(page, pageQuery);
    }
    @Override
    public OaApprovalApplicationAssetDetailVO getDetail(Integer id) {
        OaApprovalApplicationAsset detail = this.getById(id);
        if (detail == null) {
            throw new ServiceException("记录不存在");
        }
        OaApprovalApplications app = oaApprovalApplicationsService.getById(detail.getApprovalApplicationId());
        if (app == null) {
            throw new ServiceException("审批主记录不存在");
        }
        List<OaApprovalApplicationAssetItem> items = oaApprovalApplicationAssetItemService.lambdaQuery()
                .eq(OaApprovalApplicationAssetItem::getApprovalApplicationId, app.getId())
                .list();
        OaApprovalApplicationAssetDetailVO vo = new OaApprovalApplicationAssetDetailVO();
        vo.setItems(items);
        return vo;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OaApprovalApplicationPurchaseServiceImpl.java
@@ -10,8 +10,6 @@
import com.ruoyi.system.model.OaApprovalApplicationPurchaseItem;
import com.ruoyi.system.model.OaApprovalApplications;
import com.ruoyi.system.model.OaApprovalFlowNode;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.OaApprovalApplicationPurchaseItemService;
import com.ruoyi.system.service.OaApprovalApplicationPurchaseService;
import com.ruoyi.system.service.OaApprovalApplicationsService;
@@ -42,8 +40,6 @@
    private final OaApprovalApplicationPurchaseItemService oaApprovalApplicationPurchaseItemService;
    private final OaApprovalFlowNodeService oaApprovalFlowNodeService;
    private final OaApprovalTodoService oaApprovalTodoService;
    private final ISysUserService sysUserService;
    private final ISysDeptService sysDeptService;
    @Override
    @Transactional(rollbackFor = Exception.class)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OaApprovalApplicationStorageServiceImpl.java
@@ -20,6 +20,7 @@
import com.ruoyi.system.model.OaApprovalApplicationStorage;
import com.ruoyi.system.model.OaApprovalApplications;
import com.ruoyi.system.model.OaApprovalFlowNode;
import com.ruoyi.system.query.OaApprovalApplicationStoragePageQuery;
import com.ruoyi.system.service.AssetGeneralExtService;
import com.ruoyi.system.service.AssetMainService;
import com.ruoyi.system.service.AssetPropertyExtService;
@@ -33,8 +34,8 @@
import com.ruoyi.system.service.OaApprovalFlowNodeService;
import com.ruoyi.system.service.OaApprovalTodoService;
import com.ruoyi.system.service.TDeptService;
import com.ruoyi.system.vo.asset.OaApprovalApplicationStoragePageVO;
import com.ruoyi.system.vo.asset.OaApprovalApplicationStorageGeneralDetailVO;
import com.ruoyi.system.vo.asset.OaApprovalApplicationStoragePageVO;
import com.ruoyi.system.vo.asset.OaApprovalApplicationStoragePropertyDetailVO;
import com.ruoyi.system.vo.asset.OaApprovalApplicationStorageVehicleDetailVO;
import lombok.RequiredArgsConstructor;
@@ -146,8 +147,7 @@
     */
    private void saveGeneralAssets(List<OaApprovalApplicationStorageGeneralDTO.GeneralAssetItemDTO> assetItems, Integer applicationId, Integer assetTypeId, LocalDate storageDate, OaApprovalApplicationStorageGeneralDTO baseDto) {
        List<AssetMain> allAssetMains = new ArrayList<>();
        List<AssetGeneralExt> allGeneralExts = new ArrayList<>();
        for (OaApprovalApplicationStorageGeneralDTO.GeneralAssetItemDTO item : assetItems) {
            // 根据数量创建对应数量的资产记录
            int quantity = item.getQuantity().intValue();
@@ -162,19 +162,6 @@
        
        // 批量保存资产主表数据
        assetMainService.saveBatch(allAssetMains);
        // 为每个资产主表记录创建对应的扩展信息
        int assetMainIndex = 0;
        for (OaApprovalApplicationStorageGeneralDTO.GeneralAssetItemDTO item : assetItems) {
            int quantity = item.getQuantity().intValue();
            for (int i = 0; i < quantity; i++) {
                AssetGeneralExt generalExt = buildAssetGeneralExt(item, allAssetMains.get(assetMainIndex).getId());
                allGeneralExts.add(generalExt);
                assetMainIndex++;
            }
        }
        assetGeneralExtService.saveBatch(allGeneralExts);
    }
    /**
@@ -258,12 +245,21 @@
        assetMain.setAssetOriginalCode(item.getAssetOriginalCode());
        assetMain.setAssetCode(generateAssetCode(assetTypeId, storageDate)); // 系统生成资产编码
        assetMain.setAssetName(item.getAssetName());
        assetMain.setCategory(item.getCategory());
        assetMain.setSpecificationModel(item.getSpecificationModel());
        assetMain.setAssetTypeId(assetTypeId);
        assetMain.setMeasurementUnit(item.getMeasurementUnit());
        assetMain.setUnitPrice(item.getUnitPrice());
        assetMain.setUsefulLife(item.getUsefulLife());
        assetMain.setOwnershipDeptId(item.getOwnershipDeptId());
        // 根据权属单位/部门名称填充ID
        if (item.getOwnershipDeptName() != null && !item.getOwnershipDeptName().isEmpty()) {
            TDept ownerDept = tDeptService.lambdaQuery()
                    .eq(TDept::getDeptName, item.getOwnershipDeptName())
                    .one();
            if (ownerDept != null) {
                assetMain.setOwnershipDeptId(ownerDept.getId());
            }
        }
        assetMain.setUserName(item.getUserName());
        // 根据整单 addressType 写入使用部门ID或仓库ID
        applyAddressToAssetMain(assetMain, baseDto.getAddressType(), baseDto.getUseDeptName(), baseDto.getWarehouseName(), baseDto.getAddress());
@@ -288,12 +284,20 @@
        assetMain.setAssetOriginalCode(item.getAssetOriginalCode());
        assetMain.setAssetCode(generateAssetCode(assetTypeId, storageDate));
        assetMain.setAssetName(item.getAssetName());
        assetMain.setCategory(item.getCategory());
        assetMain.setSpecificationModel(item.getSpecificationModel());
        assetMain.setAssetTypeId(assetTypeId);
        assetMain.setMeasurementUnit(item.getMeasurementUnit());
        assetMain.setUnitPrice(item.getUnitPrice());
        assetMain.setUsefulLife(item.getUsefulLife());
        assetMain.setOwnershipDeptId(item.getOwnershipDeptId());
        if (item.getOwnershipDeptName() != null && !item.getOwnershipDeptName().isEmpty()) {
            TDept ownerDept = tDeptService.lambdaQuery()
                    .eq(TDept::getDeptName, item.getOwnershipDeptName())
                    .one();
            if (ownerDept != null) {
                assetMain.setOwnershipDeptId(ownerDept.getId());
            }
        }
        assetMain.setUserName(item.getUserName());
        applyAddressToAssetMain(assetMain, baseDto.getAddressType(), baseDto.getUseDeptName(), baseDto.getWarehouseName(), baseDto.getAddress());
        assetMain.setAssetMainType(baseDto.getAddressType());
@@ -317,12 +321,20 @@
        assetMain.setAssetOriginalCode(item.getAssetOriginalCode());
        assetMain.setAssetCode(generateAssetCode(assetTypeId, storageDate));
        assetMain.setAssetName(item.getAssetName());
        assetMain.setCategory(item.getCategory());
        assetMain.setSpecificationModel(item.getSpecificationModel());
        assetMain.setAssetTypeId(assetTypeId);
        assetMain.setMeasurementUnit(item.getMeasurementUnit());
        assetMain.setUnitPrice(item.getUnitPrice());
        assetMain.setUsefulLife(item.getUsefulLife());
        assetMain.setOwnershipDeptId(item.getOwnershipDeptId());
        if (item.getOwnershipDeptName() != null && !item.getOwnershipDeptName().isEmpty()) {
            TDept ownerDept = tDeptService.lambdaQuery()
                    .eq(TDept::getDeptName, item.getOwnershipDeptName())
                    .one();
            if (ownerDept != null) {
                assetMain.setOwnershipDeptId(ownerDept.getId());
            }
        }
        assetMain.setUserName(item.getUserName());
        applyAddressToAssetMain(assetMain, baseDto.getAddressType(), baseDto.getUseDeptName(), baseDto.getWarehouseName(), baseDto.getAddress());
        assetMain.setAssetMainType(baseDto.getAddressType());
@@ -383,16 +395,6 @@
    private AssetGeneralExt buildAssetGeneralExt(OaApprovalApplicationStorageGeneralDTO.GeneralAssetItemDTO item, Integer assetMainId) {
        AssetGeneralExt generalExt = new AssetGeneralExt();
        generalExt.setAssetMainId(assetMainId);
        generalExt.setSupplierName(item.getSupplierName());
        generalExt.setPurchaseDate(item.getPurchaseDate());
        generalExt.setWarrantyPeriod(item.getWarrantyPeriod());
        generalExt.setWarrantyExpireDate(item.getWarrantyExpireDate());
        generalExt.setDepreciationMethod(item.getDepreciationMethod());
        generalExt.setDepreciationRate(item.getDepreciationRate());
        generalExt.setNetValue(item.getNetValue());
        generalExt.setMaintenanceCycle(item.getMaintenanceCycle());
        generalExt.setLastMaintenanceDate(item.getLastMaintenanceDate());
        generalExt.setNextMaintenanceDate(item.getNextMaintenanceDate());
        generalExt.setDisabled(false);
        return generalExt;
    }
@@ -414,7 +416,7 @@
        propertyExt.setDetailedLocation(item.getDetailedLocation());
        propertyExt.setProvincialPlatformValue(item.getProvincialPlatformValue());
        propertyExt.setResettlementSituation(item.getResettlementSituation());
        propertyExt.setIsMortgaged(item.getIsMortgaged());
        propertyExt.setMortgaged(item.getMortgaged());
        propertyExt.setTenantName(item.getTenantName());
        propertyExt.setRentalAmount(item.getRentalAmount());
        propertyExt.setLeaseStartDate(item.getLeaseStartDate());
@@ -472,7 +474,7 @@
            applications.setApplicantName(generalDTO.getApplicantName());
            applications.setDeptId(generalDTO.getDeptId());
            applications.setDeptName(generalDTO.getDeptName());
            applications.setApplicationDate(generalDTO.getApplicationDate());
            applications.setApplicationDate(LocalDate.now());
            applications.setApplicationReason(generalDTO.getApplicationReason());
            applications.setAttachmentUrl(generalDTO.getAttachmentUrl());
        } else if (dto instanceof OaApprovalApplicationStoragePropertyDTO) {
@@ -481,7 +483,7 @@
            applications.setApplicantName(propertyDTO.getApplicantName());
            applications.setDeptId(propertyDTO.getDeptId());
            applications.setDeptName(propertyDTO.getDeptName());
            applications.setApplicationDate(propertyDTO.getApplicationDate());
            applications.setApplicationDate(LocalDate.now());
            applications.setApplicationReason(propertyDTO.getApplicationReason());
            applications.setAttachmentUrl(propertyDTO.getAttachmentUrl());
        } else if (dto instanceof OaApprovalApplicationStorageVehicleDTO) {
@@ -490,7 +492,7 @@
            applications.setApplicantName(vehicleDTO.getApplicantName());
            applications.setDeptId(vehicleDTO.getDeptId());
            applications.setDeptName(vehicleDTO.getDeptName());
            applications.setApplicationDate(vehicleDTO.getApplicationDate());
            applications.setApplicationDate(LocalDate.now());
            applications.setApplicationReason(vehicleDTO.getApplicationReason());
            applications.setAttachmentUrl(vehicleDTO.getAttachmentUrl());
        }
@@ -577,7 +579,7 @@
    }
    
    @Override
    public IPage<OaApprovalApplicationStoragePageVO> getPageList(com.ruoyi.system.query.OaApprovalApplicationStoragePageQuery pageQuery) {
    public IPage<OaApprovalApplicationStoragePageVO> getPageList(OaApprovalApplicationStoragePageQuery pageQuery) {
        Page<OaApprovalApplicationStoragePageVO> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
        return this.baseMapper.selectApplicationStoragePage(page, pageQuery);
    }
@@ -604,8 +606,11 @@
        if (!CollectionUtils.isEmpty(mains)) {
            List<Integer> mainIds = mains.stream().map(AssetMain::getId).collect(Collectors.toList());
            List<AssetGeneralExt> exts = assetGeneralExtService.lambdaQuery().in(AssetGeneralExt::getAssetMainId, mainIds).list();
            Map<Integer, AssetGeneralExt> extMap = exts.stream().collect(Collectors.toMap(AssetGeneralExt::getAssetMainId, e -> e));
            // 批量查询权属部门,避免循环内查询
            List<Integer> ownerIds = mains.stream().map(AssetMain::getOwnershipDeptId)
                    .filter(id -> id != null).distinct().collect(Collectors.toList());
            Map<Integer, TDept> ownerDeptMap = ownerIds.isEmpty() ? java.util.Collections.emptyMap()
                    : tDeptService.listByIds(ownerIds).stream().collect(Collectors.toMap(TDept::getId, d -> d));
            List<OaApprovalApplicationStorageGeneralDetailVO.GeneralAssetItemVO> items = mains.stream().map(m -> {
                OaApprovalApplicationStorageGeneralDetailVO.GeneralAssetItemVO item = new OaApprovalApplicationStorageGeneralDetailVO.GeneralAssetItemVO();
@@ -616,7 +621,10 @@
                item.setQuantity(m.getQuantity());
                item.setUnitPrice(m.getUnitPrice());
                item.setUsefulLife(m.getUsefulLife());
                item.setOwnershipDeptId(m.getOwnershipDeptId());
                if (m.getOwnershipDeptId() != null) {
                    TDept dept = ownerDeptMap.get(m.getOwnershipDeptId());
                    item.setOwnerShipDeptName(dept != null ? dept.getDeptName() : null);
                }
                item.setUserName(m.getUserName());
                item.setAssetStatus(m.getAssetStatus());
                item.setRemarks(m.getRemarks());
@@ -625,19 +633,6 @@
                item.setAccountingVoucherNo(m.getAccountingVoucherNo());
                item.setAccountingSubject(m.getAccountingSubject());
                item.setAccountingAmount(m.getAccountingAmount());
                AssetGeneralExt ext = extMap.get(m.getId());
                if (ext != null) {
                    item.setSupplierName(ext.getSupplierName());
                    item.setPurchaseDate(ext.getPurchaseDate());
                    item.setWarrantyPeriod(ext.getWarrantyPeriod());
                    item.setWarrantyExpireDate(ext.getWarrantyExpireDate());
                    item.setDepreciationMethod(ext.getDepreciationMethod());
                    item.setDepreciationRate(ext.getDepreciationRate());
                    item.setNetValue(ext.getNetValue());
                    item.setMaintenanceCycle(ext.getMaintenanceCycle());
                    item.setLastMaintenanceDate(ext.getLastMaintenanceDate());
                    item.setNextMaintenanceDate(ext.getNextMaintenanceDate());
                }
                return item;
            }).collect(Collectors.toList());
            vo.setAssetItems(items);
@@ -669,6 +664,11 @@
            List<Integer> mainIds = mains.stream().map(AssetMain::getId).collect(Collectors.toList());
            List<AssetPropertyExt> exts = assetPropertyExtService.lambdaQuery().in(AssetPropertyExt::getAssetMainId, mainIds).list();
            Map<Integer, AssetPropertyExt> extMap = exts.stream().collect(Collectors.toMap(AssetPropertyExt::getAssetMainId, e -> e));
            // 批量查询权属部门
            List<Integer> ownerIds = mains.stream().map(AssetMain::getOwnershipDeptId)
                    .filter(id -> id != null).distinct().collect(Collectors.toList());
            Map<Integer, TDept> ownerDeptMap = ownerIds.isEmpty() ? java.util.Collections.emptyMap()
                    : tDeptService.listByIds(ownerIds).stream().collect(Collectors.toMap(TDept::getId, d -> d));
            List<OaApprovalApplicationStoragePropertyDetailVO.PropertyAssetItemVO> items = mains.stream().map(m -> {
                OaApprovalApplicationStoragePropertyDetailVO.PropertyAssetItemVO item = new OaApprovalApplicationStoragePropertyDetailVO.PropertyAssetItemVO();
@@ -679,7 +679,10 @@
                item.setQuantity(m.getQuantity());
                item.setUnitPrice(m.getUnitPrice());
                item.setUsefulLife(m.getUsefulLife());
                item.setOwnershipDeptId(m.getOwnershipDeptId());
                if (m.getOwnershipDeptId() != null) {
                    TDept dept = ownerDeptMap.get(m.getOwnershipDeptId());
                    item.setOwnerShipDeptName(dept != null ? dept.getDeptName() : null);
                }
                item.setUserName(m.getUserName());
                item.setAssetStatus(m.getAssetStatus());
                item.setRemarks(m.getRemarks());
@@ -701,7 +704,7 @@
                    item.setDetailedLocation(ext.getDetailedLocation());
                    item.setProvincialPlatformValue(ext.getProvincialPlatformValue());
                    item.setResettlementSituation(ext.getResettlementSituation());
                    item.setIsMortgaged(ext.getIsMortgaged());
                    item.setMortgaged(ext.getMortgaged());
                    item.setTenantName(ext.getTenantName());
                    item.setRentalAmount(ext.getRentalAmount());
                    item.setLeaseStartDate(ext.getLeaseStartDate());
@@ -738,6 +741,11 @@
            List<Integer> mainIds = mains.stream().map(AssetMain::getId).collect(Collectors.toList());
            List<AssetVehicleExt> exts = assetVehicleExtService.lambdaQuery().in(AssetVehicleExt::getAssetMainId, mainIds).list();
            Map<Integer, AssetVehicleExt> extMap = exts.stream().collect(Collectors.toMap(AssetVehicleExt::getAssetMainId, e -> e));
            // 批量查询权属部门
            List<Integer> ownerIds = mains.stream().map(AssetMain::getOwnershipDeptId)
                    .filter(id -> id != null).distinct().collect(Collectors.toList());
            Map<Integer, TDept> ownerDeptMap = ownerIds.isEmpty() ? java.util.Collections.emptyMap()
                    : tDeptService.listByIds(ownerIds).stream().collect(Collectors.toMap(TDept::getId, d -> d));
            List<OaApprovalApplicationStorageVehicleDetailVO.VehicleAssetItemVO> items = mains.stream().map(m -> {
                OaApprovalApplicationStorageVehicleDetailVO.VehicleAssetItemVO item = new OaApprovalApplicationStorageVehicleDetailVO.VehicleAssetItemVO();
@@ -748,7 +756,10 @@
                item.setQuantity(m.getQuantity());
                item.setUnitPrice(m.getUnitPrice());
                item.setUsefulLife(m.getUsefulLife());
                item.setOwnershipDeptId(m.getOwnershipDeptId());
                if (m.getOwnershipDeptId() != null) {
                    TDept dept = ownerDeptMap.get(m.getOwnershipDeptId());
                    item.setOwnerShipDeptName(dept != null ? dept.getDeptName() : null);
                }
                item.setUserName(m.getUserName());
                item.setAssetStatus(m.getAssetStatus());
                item.setRemarks(m.getRemarks());
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OssServiceImpl.java
New file
@@ -0,0 +1,119 @@
package com.ruoyi.system.service.impl;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.ruoyi.common.config.FileUploadConfig;
import com.ruoyi.common.config.OssConfig;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.service.OssService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;
/**
 * @author mitao
 * @date 2024/12/23
 */
@Service
public class OssServiceImpl implements OssService {
    @Autowired
    private FileUploadConfig fileUploadConfig;
    /**
     * 文件上传
     *
     * @param file
     * @return
     */
    @Override
    public String uploadFile(MultipartFile file) throws IOException {
        if (Objects.isNull(file)) {
            throw new ServiceException("文件不能为空");
        }
        // 获取文件名称
        String filename = file.getOriginalFilename();
        // 获取文件后缀
        String ext = filename.substring(filename.lastIndexOf("."), filename.length());
        // 检查文件类型
        if (!fileUploadConfig.getAllowExt().contains(ext)) {
            throw new ServiceException("上传文件格式不正确,仅支持"+ fileUploadConfig.getAllowExt());
        }
        return upload(OssConfig.FOLDER, file);
    }
    /**
     * 文件上传,指定上传路径
     *
     * @param storagePath
     * @param file
     * @return
     */
    @Override
    public String upload(String storagePath, MultipartFile file) throws IOException {
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(OssConfig.ACCESS_KEY_ID, OssConfig.ACCESS_KEY_SECRET);
        String region = "cn-chengdu";
        // 创建OSSClient实例。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(OssConfig.UPLOAD_ENDPOINT)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();
        InputStream inputStream = file.getInputStream();
        String originFileName = file.getOriginalFilename();
        String fileExt = Objects.requireNonNull(originFileName).substring(originFileName.lastIndexOf(".") + 1);
        String fileName = originFileName.substring(0, originFileName.lastIndexOf("."));
        // 设置文件名
        String filePathName = generateRelativeStoragePath(storagePath, fileExt, fileName);
        // 创建PutObjectRequest对象。
        PutObjectRequest putObjectRequest = new PutObjectRequest(OssConfig.BUCKET_NAME, filePathName, inputStream);
        // 创建PutObject请求。
        PutObjectResult result = ossClient.putObject(putObjectRequest);
        return OssConfig.DOWNLOAD_ENDPOINT + filePathName;
    }
    /**
     * <pre>
     * 获取存储的相对路径
     * 规则path + / + yyyyMMddHH  + uuid
     * </pre>
     *
     * @param storagePath
     * @return
     */
    private static String generateRelativeStoragePath(String storagePath, String fileType, String fileName) {
        String time = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
        String uuid = UUID.randomUUID().toString();
        StringBuilder sb = new StringBuilder();
        if (StringUtils.isNotBlank(storagePath)) {
            sb.append(storagePath).append("/");
        }
        if (fileName == null) {
            sb.append(time).append(uuid);
        } else {
            sb.append(fileName).append(time);
        }
        if (StringUtils.isNotBlank(fileType)) {
            sb.append(".").append(fileType);
        }
        return sb.toString();
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/OaApprovalApplicationAssetDetailVO.java
New file
@@ -0,0 +1,78 @@
package com.ruoyi.system.vo.asset;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.system.model.OaApprovalApplicationAssetItem;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
/**
 * 资产领用/借用/归还 详情VO
 */
@Data
@ApiModel("资产领用/借用/归还 详情VO")
public class OaApprovalApplicationAssetDetailVO implements Serializable {
    @ApiModelProperty(value = "主键")
    private Integer id;
    @ApiModelProperty(value = "申请单号")
    private String applicationCode;
    @ApiModelProperty(value = "审批ID")
    private Integer approvalId;
    @ApiModelProperty(value = "申请人ID")
    private Integer applicantUserId;
    @ApiModelProperty(value = "申请人")
    private String applicantName;
    @ApiModelProperty(value = "所属部门")
    private String deptName;
    @ApiModelProperty(value = "部门ID")
    private Integer deptId;
    @ApiModelProperty(value = "申请日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate applicationDate;
    @ApiModelProperty(value = "事由/原因/说明")
    private String applicationReason;
    @ApiModelProperty(value = "审批状态 0-草稿,1-待审批,2-审批通过,3-审批拒绝 ,4-已撤回")
    private Integer approvalStatus;
    @ApiModelProperty(value = "附件地址,多个使用英文逗号拼接")
    private String attachmentUrl;
    @ApiModelProperty(value = "当前流程id")
    private Integer currentFlowNodeId;
    @ApiModelProperty(value = "事项标题")
    private String title;
    @ApiModelProperty(value = "资产类型")
    private Integer assetTypeId;
    @ApiModelProperty(value = "领用/借用日期")
    private LocalDate operateTime;
    @ApiModelProperty(value = "预计退还日期")
    private LocalDate expectReturnDate;
    @ApiModelProperty(value = "操作类型 0-领用,1-借用,2-归还")
    private Integer type;
    @ApiModelProperty(value = "借用审批ID,类型为归还时使用。")
    private Integer borrowApplicationId;
    @ApiModelProperty("关联资产项列表")
    private List<OaApprovalApplicationAssetItem> items;
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/OaApprovalApplicationAssetPageVO.java
New file
@@ -0,0 +1,47 @@
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.io.Serializable;
import java.time.LocalDate;
/**
 * 资产领用申请分页列表返回对象
 */
@Data
@ApiModel("资产领用申请分页列表返回对象")
public class OaApprovalApplicationAssetPageVO implements Serializable {
    private static final long serialVersionUID = 4352345234523452346L;
    @ApiModelProperty("主键ID")
    private Integer id;
    @ApiModelProperty("单据号")
    private String applicationCode;
    @ApiModelProperty("标题")
    private String title;
    @ApiModelProperty("领用部门")
    private String deptName;
    @ApiModelProperty("领用人")
    private String applicantName;
    @ApiModelProperty("资产一级类型名称")
    private String firstAssetTypeName;
    @ApiModelProperty("资产二级类型名称")
    private String secondAssetTypeName;
    @ApiModelProperty("领用日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate operateTime;
    @ApiModelProperty("状态 0-草稿,1-待审批,2-通过,3-拒绝,4-撤回")
    private Integer approvalStatus;
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/OaApprovalApplicationStorageGeneralDetailVO.java
@@ -88,8 +88,8 @@
        @ApiModelProperty(value = "使用年限(年)")
        private Integer usefulLife;
        @ApiModelProperty(value = "权属单位/部门ID")
        private Integer ownershipDeptId;
        @ApiModelProperty(value = "权属单位/部门名称")
        private String ownerShipDeptName;
        @ApiModelProperty(value = "使用人")
        private String userName;
@@ -114,37 +114,5 @@
        @ApiModelProperty(value = "入账金额")
        private BigDecimal accountingAmount;
        // 通用资产扩展表字段
        @ApiModelProperty(value = "供应商名称")
        private String supplierName;
        @ApiModelProperty(value = "采购日期")
        private LocalDate purchaseDate;
        @ApiModelProperty(value = "保修期(月)")
        private Integer warrantyPeriod;
        @ApiModelProperty(value = "保修到期日期")
        private LocalDate warrantyExpireDate;
        @ApiModelProperty(value = "折旧方法")
        private String depreciationMethod;
        @ApiModelProperty(value = "折旧率")
        private java.math.BigDecimal depreciationRate;
        @ApiModelProperty(value = "净值")
        private java.math.BigDecimal netValue;
        @ApiModelProperty(value = "维护周期(月)")
        private Integer maintenanceCycle;
        @ApiModelProperty(value = "上次维护日期")
        private LocalDate lastMaintenanceDate;
        @ApiModelProperty(value = "下次维护日期")
        private LocalDate nextMaintenanceDate;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/OaApprovalApplicationStoragePropertyDetailVO.java
@@ -1,5 +1,6 @@
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;
@@ -88,8 +89,8 @@
        @ApiModelProperty(value = "使用年限(年)")
        private Integer usefulLife;
        @ApiModelProperty(value = "权属单位/部门ID")
        private Integer ownershipDeptId;
        @ApiModelProperty(value = "权属单位/部门名称")
        private String ownerShipDeptName;
        @ApiModelProperty(value = "使用人")
        private String userName;
@@ -150,7 +151,7 @@
        private String resettlementSituation;
        @ApiModelProperty(value = "是否抵押:0-否,1-是")
        private Boolean isMortgaged;
        private Integer mortgaged;
        @ApiModelProperty(value = "承租方")
        private String tenantName;
@@ -159,10 +160,11 @@
        private BigDecimal rentalAmount;
        @ApiModelProperty(value = "租赁期限起")
        @JsonFormat(pattern = "yyyy-MM-dd")
        private LocalDate leaseStartDate;
        @ApiModelProperty(value = "租赁期限止")
        @JsonFormat(pattern = "yyyy-MM-dd")
        private LocalDate leaseEndDate;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/asset/OaApprovalApplicationStorageVehicleDetailVO.java
@@ -88,8 +88,8 @@
        @ApiModelProperty(value = "使用年限(年)")
        private Integer usefulLife;
        @ApiModelProperty(value = "权属单位/部门ID")
        private Integer ownershipDeptId;
        @ApiModelProperty(value = "权属单位/部门名称")
        private String ownerShipDeptName;
        @ApiModelProperty(value = "使用人")
        private String userName;
@@ -141,4 +141,3 @@
        private String propertyRightForm;
    }
}
ruoyi-system/src/main/resources/mapper/system/OaApprovalApplicationAssetMapper.xml
@@ -17,6 +17,40 @@
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, approval_application_id, title, asset_type_id, operate_time, expect_return_date, type, borrow_application_id
    </sql>
</sql>
    <!-- 分页查询:资产领用申请列表(关联审批记录与资产类型) -->
    <select id="selectReceivePage" resultType="com.ruoyi.system.vo.asset.OaApprovalApplicationAssetPageVO">
        SELECT
            oaa.id                               AS id,
            aaa.application_code                 AS applicationCode,
            oaa.title                            AS title,
            aaa.dept_name                        AS deptName,
            aaa.applicant_name                   AS applicantName,
            CASE WHEN at2.level = 2 THEN at1.type_name ELSE at2.type_name END AS firstAssetTypeName,
            CASE WHEN at2.level = 2 THEN at2.type_name ELSE NULL END         AS secondAssetTypeName,
            oaa.operate_time                     AS operateTime,
            aaa.approval_status                  AS approvalStatus
        FROM oa_approval_application_asset oaa
                 INNER JOIN oa_approval_applications aaa ON aaa.id = oaa.approval_application_id
                 LEFT JOIN asset_type at2 ON at2.id = oaa.asset_type_id
                 LEFT JOIN asset_type at1 ON at1.id = (CASE WHEN at2.level = 2 THEN at2.parent_id ELSE at2.id END)
        <where>
            AND aaa.disabled = 0
            AND oaa.type = 0
            <if test="query != null and query.keyword != null and query.keyword != ''">
                AND (
                    oaa.title LIKE CONCAT('%', #{query.keyword}, '%')
                    OR  aaa.application_code LIKE CONCAT('%', #{query.keyword}, '%')
                    OR  aaa.dept_name LIKE CONCAT('%', #{query.keyword}, '%')
                    OR  aaa.applicant_name LIKE CONCAT('%', #{query.keyword}, '%')
                )
            </if>
            <if test="query != null and query.deptId != null">
                AND aaa.dept_id = #{query.deptId}
            </if>
        </where>
        ORDER BY oaa.operate_time DESC, oaa.id DESC
    </select>
</mapper>
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -266,7 +266,7 @@
    select  * from sys_user
    where 1=1
        <if test="ids != null and ids.size()>0">
            AND deptId IN
            AND dept_id IN
            <foreach collection="ids" separator="," item="id" open="(" close=")">
                #{id}
            </foreach>
@@ -277,7 +277,7 @@
    <select id="selectListByDeptId" resultType="com.ruoyi.common.core.domain.entity.SysUser">
        select u.*
        from sys_user u where u.deptId = #{deptId} and u.status = 0 and u.del_flag = 0
        from sys_user u where u.dept_id = #{deptId} and u.status = 0 and u.del_flag = 0
    </select>
    <select id="selectListByDeptType" resultType="com.ruoyi.common.core.domain.entity.SysUser">
        select u.*
@@ -287,7 +287,7 @@
        select u.*
        from sys_user u where u.status = 0 and u.del_flag = 0
        <if test="projectIds != null and projectIds.size() > 0">
            and u.deptId in
            and u.dept_id in
            <foreach item="item" collection="projectIds" open="(" separator="," close=")">
                #{item}
            </foreach>
@@ -299,7 +299,7 @@
            and deptType = #{deptType}
        </if>
        <if test="projectIds != null and projectIds.size() > 0">
            and deptId in
            and dept_id in
            <foreach item="item" collection="projectIds" open="(" separator="," close=")">
                #{item}
            </foreach>