gaoluyang
昨天 90b3ad820eea45d021835197eac5bc3ad55b12ed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package cn.iocoder.yudao.module.finance.controller.admin.asset;
 
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.finance.controller.admin.asset.vo.FinFixedAssetDepreciateRespVO;
import cn.iocoder.yudao.module.finance.controller.admin.asset.vo.FinFixedAssetPageReqVO;
import cn.iocoder.yudao.module.finance.controller.admin.asset.vo.FinFixedAssetRespVO;
import cn.iocoder.yudao.module.finance.controller.admin.asset.vo.FinFixedAssetSaveReqVO;
import cn.iocoder.yudao.module.finance.dal.dataobject.asset.FinFixedAssetDO;
import cn.iocoder.yudao.module.finance.service.asset.FinAssetAmountUtils;
import cn.iocoder.yudao.module.finance.service.asset.FinFixedAssetService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
 
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 
@Tag(name = "管理后台 - 固定资产")
@RestController
@RequestMapping("/finance/fixed-asset")
@Validated
public class FinFixedAssetController {
 
    @Resource
    private FinFixedAssetService fixedAssetService;
    @Resource
    private DeptApi deptApi;
    @Resource
    private AdminUserApi adminUserApi;
 
    @PostMapping("/create")
    @Operation(summary = "创建固定资产")
    @PreAuthorize("@ss.hasPermission('finance:fixed-asset:create')")
    public CommonResult<Long> createFixedAsset(@Valid @RequestBody FinFixedAssetSaveReqVO createReqVO) {
        return success(fixedAssetService.createFixedAsset(createReqVO));
    }
 
    @PutMapping("/update")
    @Operation(summary = "更新固定资产")
    @PreAuthorize("@ss.hasPermission('finance:fixed-asset:update')")
    public CommonResult<Boolean> updateFixedAsset(@Valid @RequestBody FinFixedAssetSaveReqVO updateReqVO) {
        fixedAssetService.updateFixedAsset(updateReqVO);
        return success(true);
    }
 
    @DeleteMapping("/delete")
    @Operation(summary = "删除固定资产")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('finance:fixed-asset:delete')")
    public CommonResult<Boolean> deleteFixedAsset(@RequestParam("id") Long id) {
        fixedAssetService.deleteFixedAsset(id);
        return success(true);
    }
 
    @DeleteMapping("/delete-list")
    @Operation(summary = "批量删除固定资产")
    @Parameter(name = "ids", description = "编号列表", required = true)
    @PreAuthorize("@ss.hasPermission('finance:fixed-asset:delete')")
    public CommonResult<Boolean> deleteFixedAssetList(@RequestParam("ids") List<Long> ids) {
        fixedAssetService.deleteFixedAssetList(ids);
        return success(true);
    }
 
    @PostMapping("/depreciate")
    @Operation(summary = "计提折旧", description = "按资产逐个计提一个月的折旧;ids 为空时对所有未报废资产计提")
    @Parameter(name = "ids", description = "资产编号列表,为空表示全部", required = false)
    @PreAuthorize("@ss.hasPermission('finance:fixed-asset:depreciate')")
    public CommonResult<FinFixedAssetDepreciateRespVO> depreciateFixedAssetList(
            @RequestParam(value = "ids", required = false) List<Long> ids) {
        return success(fixedAssetService.depreciateFixedAssetList(ids));
    }
 
    @GetMapping("/get")
    @Operation(summary = "获得固定资产")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('finance:fixed-asset:query')")
    public CommonResult<FinFixedAssetRespVO> getFixedAsset(@RequestParam("id") Long id) {
        FinFixedAssetDO asset = fixedAssetService.getFixedAsset(id);
        if (asset == null) {
            return success(null);
        }
        FinFixedAssetRespVO respVO = toRespVO(asset);
        fillDepartmentAndKeeper(List.of(respVO));
        return success(respVO);
    }
 
    @GetMapping("/page")
    @Operation(summary = "获得固定资产分页")
    @PreAuthorize("@ss.hasPermission('finance:fixed-asset:query')")
    public CommonResult<PageResult<FinFixedAssetRespVO>> getFixedAssetPage(@Valid FinFixedAssetPageReqVO pageReqVO) {
        PageResult<FinFixedAssetDO> pageResult = fixedAssetService.getFixedAssetPage(pageReqVO);
        PageResult<FinFixedAssetRespVO> result = BeanUtils.toBean(pageResult, FinFixedAssetRespVO.class,
                this::fillMonthlyDepreciation);
        fillDepartmentAndKeeper(result.getList());
        return success(result);
    }
 
    @GetMapping("/list")
    @Operation(summary = "获得固定资产列表")
    @PreAuthorize("@ss.hasPermission('finance:fixed-asset:query')")
    public CommonResult<List<FinFixedAssetRespVO>> getFixedAssetList() {
        List<FinFixedAssetDO> list = fixedAssetService.getFixedAssetList();
        List<FinFixedAssetRespVO> voList = convertList(list, this::toRespVO);
        fillDepartmentAndKeeper(voList);
        return success(voList);
    }
 
    @GetMapping("/export-excel")
    @Operation(summary = "导出固定资产 Excel")
    @PreAuthorize("@ss.hasPermission('finance:fixed-asset:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportFixedAssetExcel(@Valid FinFixedAssetPageReqVO pageReqVO,
                                      HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<FinFixedAssetDO> list = fixedAssetService.getFixedAssetPage(pageReqVO).getList();
        List<FinFixedAssetRespVO> voList = BeanUtils.toBean(list, FinFixedAssetRespVO.class,
                this::fillMonthlyDepreciation);
        fillDepartmentAndKeeper(voList);
        // 导出 Excel
        ExcelUtils.write(response, "固定资产.xls", "数据", FinFixedAssetRespVO.class, voList);
    }
 
    private FinFixedAssetRespVO toRespVO(FinFixedAssetDO asset) {
        return fillMonthlyDepreciation(BeanUtils.toBean(asset, FinFixedAssetRespVO.class));
    }
 
    /**
     * 回填月折旧额(不落库,仅用于展示,口径与计提折旧一致)
     */
    private FinFixedAssetRespVO fillMonthlyDepreciation(FinFixedAssetRespVO respVO) {
        if (respVO.getUsefulLife() == null || respVO.getUsefulLife() <= 0
                || respVO.getOriginalValue() == null) {
            return respVO;
        }
        return respVO.setMonthlyDepreciation(FinAssetAmountUtils.calcMonthlyAmount(
                respVO.getOriginalValue(), respVO.getResidualRate(), respVO.getUsefulLife()));
    }
 
    /**
     * 批量回填「使用部门名称」与「保管人昵称」。
     *
     * DO 上存的是 departmentId / keeperId,而列表与导出要展示名称,
     * 所以按 ERP 收款单的既有口径,在这里把部门、用户各批量查一次再回填,避免逐行查库。
     * 解析不到的(部门/用户被删除、编号为空)就保持为空,不抛异常。
     */
    private void fillDepartmentAndKeeper(List<FinFixedAssetRespVO> list) {
        if (CollUtil.isEmpty(list)) {
            return;
        }
        Set<Long> deptIds = convertSet(list, FinFixedAssetRespVO::getDepartmentId,
                respVO -> respVO.getDepartmentId() != null);
        Set<Long> keeperIds = convertSet(list, FinFixedAssetRespVO::getKeeperId,
                respVO -> respVO.getKeeperId() != null);
        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(deptIds);
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(keeperIds);
        list.forEach(respVO -> {
            MapUtils.findAndThen(deptMap, respVO.getDepartmentId(),
                    dept -> respVO.setDepartmentName(dept.getName()));
            MapUtils.findAndThen(userMap, respVO.getKeeperId(),
                    user -> respVO.setKeeperName(user.getNickname()));
        });
    }
 
}