Fms-Java版开发实录:39 后续的几个小问题解决

Fms-Java版开发实录:39 后续的几个小问题解决

一边用,一边慢慢完善

随着系统的正式使用,也发现了一些小问题,做了一些修改,一一记录在此避免再次踩坑。

合同录入和修改的金额匹配问题

原来我的逻辑是,在录入合同的时候检查合同总价=合同不含税价+增值税额,如果不相等,就报错。

但是在实际操作中,发现录入的时候,如果总价为一个整数,含税价和增值税额为两位小数,即使相等也会报错,这是为什么呢,答案就是在比较Decimal类型数值的时候,没有统一到相同的小数点精度(scale),导致即使我们认为相等,但其实也不相等,解决办法也很简单,在接受录入数据的时候,强制将其全部转换为两位小数,并且采取四舍五入的办法。由于前端在浏览器那里已经限制了必须录入2位小数的数值,所以这么做其实不会损失精度。

代码修改如下:

// 判断都不为空的情况下,是否相等
if ((contract.getPriceWithoutVAT() != null) && (contract.getVAT() != null)) {
    if (!contract.getTotalPrice().setScale(2, RoundingMode.HALF_UP).equals(contract.getPriceWithoutVAT().setScale(2, RoundingMode.HALF_UP).add(contract.getVAT().setScale(2, RoundingMode.HALF_UP)))) {
        model.addAttribute("numberError", "不含税价+增值税 不等于 合同总价");
        return "pms/contract/contractAdd";
    }
}

前边的代码加上这个判断,已经保证了合同总价,含税价和税额三个都不为空。将三个数值全部统一转换成两位小数精度的Decimal类来进行比较,这样既保留了原来用户录入的金额,可以进行比较。

显示印花税类别

这个是一个非常小的改动,就是在下载数据的合同表中,加上最后一列对应的印花税类别。方便统计印花税。20227月新的印花税要来了,到时候又要做修改了。

添加按照项目显示所有合同的功能

目前没有这个功能,如果要查看合同,要么通过搜索,要么需要点到具体的合同类别中去,所以要添加这个功能方便一键查看。

Dao层添加功能

有了之前按照项目id查找全部Journal的经验,编写这个也方便多了。由于是查找合同,所以将功能添加在ContractDao中:

public interface ContractDao extends JpaRepository<Contract, Integer> {

    Set<Contract> findContractBySubject_ProjectIdOrderByCreateTime(int pid);
}

就是通过Subject再查到ProjectId,还是熟悉的套路。

Service业务层添加功能

ContractService业务层添加对应的方法,也很简单:

@Service
public class ContractService {

    // 查找某个项目对应的所有合同
    @Transactional
    public Set<Contract> findContractsByProject(int pid) {
        return contractDao.findContractBySubject_ProjectIdOrderByCreateTime(pid);
    }
}

控制器与页面

为了实现这个功能,很显然必须要添加一个新的URL

Project类中的URL方法

由于这个功能是从项目点进去,因此其URL算在Project类中。

Project类中添加一个拼接URL的方法:

    public String projectContractListURL() {
        return "/pms/project/contracts/" + id;
    }

之后就可以来编写对应的控制器和页面了。

控制器编写

由于这个功能算在Project类中,因此我们在ProjectController中加入ContractService,然后来编写一个控制器:

public class ProjectController {

    private final ProjectService projectService;
    private final ContractService contractService;

    @Autowired
    public ProjectController(ProjectService projectService,ContractService contractService) {
        this.projectService = projectService;
        this.contractService = contractService;
    }

    // 显示项目对应的全部合同
    @GetMapping("/contracts/{id}")
    public String contractsOfProject(@PathVariable("id") int id, Model model) {
        Project project = projectService.getProjectById(id);
        Set<Contract> contracts = contractService.findContractsByProject(id);
        model.addAttribute("project", project);
        model.addAttribute("contracts", contracts);
        model.addAttribute("count", contracts.size());
        return "pms/contract/contractListOfProject";
    }

这个控制器很简单,根据id查到项目和对应的所有合同,以及合同的数量。从return语句可以看到,我们要编写一个pms/contract/contractListOfProject.html的页面,下边就来编写。

页面编写

这个页面其实很简单,复制一份contractList.html来进行修改,唯一不同的就是几个小地方比如标题、面包屑导航等要稍微修改一下。

首先是标题的部分,改成如下:

<title>[[${project.projectName}]] - 合同列表</title>

然后是面包屑导航,只保留两个层级即可:

    <nav style="--bs-breadcrumb-divider: '>';" aria-label="breadcrumb" class="mt-3">
        <ol class="breadcrumb">
            <li class="breadcrumb-item" aria-current="page"><a href="/pms/project/list" th:href="@{/pms/project/list}" class="link-secondary">项目列表</a></li>
            <li class="breadcrumb-item" aria-current="page"><a href="/pms/project/list"
                                                               th:href="${project.detailURL()}"
                                                               class="link-secondary">[[${project.projectName}]]</a>
            </li>

            <li class="breadcrumb-item" aria-current="page"><a href="/pms/project/contracts"
                                                               th:href="${project.projectContractListURL()}"
                                                               class="link-secondary">合同列表</a>
            </li>
        </ol>
    </nav>

由于不会从此页面添加合同,而是到类别中添加,所以这里的一些判断和显示提示,以及添加的链接都可以删除。合同列表最后的操作也暂时删除,让这个页面暂时就纯展示即可。

列表的部分由于合同列表原来是组装的ContractData,这里只是纯合同,所以就展示一下最简单的数据即可,如下:

<table class="table table-hover" th:if="${count != 0}">
    <thead>
    <tr>
        <th>序号</th>
        <th>合同编号</th>
        <th>合同类别</th>
        <th>供应商</th>
        <th>合同名称</th>
        <th>合同总价</th>
    </tr>
    </thead>
    <tbody>
    <tr th:each="contract, control:${contracts}">
        <td th:text="${control.count}"></td>
        <td th:text="${contract.number}"></td>
        <td th:text="${contract.subject.getSubjectName()}"></td>
        <td th:text="${contract.supplier}"></td>
        <td><a href="" th:href="${contract.detailURL()}">[[${contract.name}]]</a></td>
        <td th:text="${#numbers.formatDecimal(contract.totalPrice,1,'COMMA',2,'POINT')}"></td>
    </tr>
    </tbody>
</table>

至于分页,如果以后合同特别多了,那么就在这个基础上添加分页功能吧。

最后在projectList.html中添加上每一行项目的操作中显示项目合同列表的功能就完成了。

LICENSED UNDER CC BY-NC-SA 4.0
Comment