Fms-Java版开发实录:24 合同 - 列出合同

Fms-Java版开发实录:24 合同 - 列出合同

列出合同的两种方式

其实每个内容里,最麻烦的就是新增和修改的这张表单,以及之后需要编写的一层一层汇总查询。以后都按照新增-列出-修改-删除的顺序来开发各个内容。

列出合同

列出合同其实最重要的是列出合同的付款情况,以及提示是否超付。不过由于目前没有编写到明细记录也就是Journal类,所以只能暂且列出来合同的部分信息;而且列出合同我设计了两个功能,一个是列出这个项目的所有合同,一个是列出某个预算对应的合同。

列出一个项目的所有合同

我们首先要解决的就是如何查询一个项目的所有合同,由于预算条目都从属于同一个项目,因此比较简单的办法就是查出所有的某个项目的预算,由于我们必须要去重,所以在给Dao编写方法的时候,不能使用List,而要使用Set

public interface ContractDao extends JpaRepository<Contract, Integer> {

    List<Contract> findContractsByBudgetsContains(Budget budget);

    boolean existsByNumber(String number);

    Set<Contract> findContractsByBudgetsIn(List<Budget> budgets);

}

这样我们先查出某个项目的所有预算条目,然后将这些预算条目所属的合同全部找出来,也就找到了这个项目的所有合同。
然后看我们的URL,给Project类再加上一条生成URL的方法:

 public String contractListUrl() {
        return "/pms/contract/project/" + id + "/list";
    }

之后就是控制器了,比较简单:

@GetMapping("/project/{pid}/list")
public String contractListByProject(@PathVariable("pid") int pid, Model model) {
    Project project = projectService.findById(pid);
    List<Budget> budgets = budgetService.getBudgetByProjectId(pid);
    Set<Contract> contracts = contractService.getContractsByBudgets(budgets);
    model.addAttribute("contracts", contracts);
    model.addAttribute("project", project);
    model.addAttribute("count", contracts.size());

    return "pms/contract/contractListProject";
}

这里就利用了刚刚编写的方法,找到一个项目对应的所有合同然后传入页面,页面现在写了一个最简单的迭代展示,还有一些字段需要之后来展示:

<main class="container">

    <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.absoluteUrl()}"
                                                               class="link-secondary">[[${project.projectName}]]</a>
            </li>
            <li class="breadcrumb-item" aria-current="page"><a href="/pms/project/list"
                                                               th:href="${project.contractListUrl()}"
                                                               class="link-secondary">合同列表</a>
            </li>
        </ol>
    </nav>
    <div class="row py-1" >
        <div class="col-sm-4"></div>
        <div th:if="${created}" class="text-center alert alert-success col-12 col-sm-4" role="alert">
            [[${created}]]
        </div>
        <div th:if="${updated}" class="text-center alert alert-success col-12 col-sm-4" role="alert">
            [[${updated}]]
        </div>
        <div th:if="${deleted}" class="text-center alert alert-success col-12 col-sm-4" role="alert">
            [[${deleted}]]
        </div>
        <div class="col-sm-4"></div>
    </div>
    <p>
        <a class="btn btn-primary" href="/pms/project/add" th:href="${project.addContractUrl()}"><i class="fas fa-plus"></i>&nbsp;新增合同</a>
    </p>
    <table class="table table-hover" th:if="${count != 0}">
        <thead>
        <tr>
            <th>合同编号</th>
            <th>合同名称</th>
            <th>合同总价</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="contract, control:${contracts}">
            <td th:text="${contract.number}"></td>
            <td th:text="${contract.name}"></td>
            <td th:text="${#numbers.formatDecimal(contract.totalPrice,0,'COMMA',2,'POINT')}"></td>
        </tr>
        </tbody>
    </table>

</main>

列出一个预算条目对应的所有合同

由于这个URL中的变量是bid,自然就把生成URL的方法写在Budget类中:

    public String contractListUrl() {
        return "/pms/contract/budget/" + id + "/list";
    }

控制器稍稍有所不同,需要将Budget对象也传入模型中:

@GetMapping("/budget/{bid}/list")
public String contractListByBudget(@PathVariable("bid") int bid, Model model) {
    Budget budget = budgetService.findById(bid);
    Project project = budget.getProject();
    Set<Contract> contracts = contractService.getContractBySingleBudget(budget);
    model.addAttribute("budget", budget);
    model.addAttribute("contracts", contracts);
    model.addAttribute("project", project);
    model.addAttribute("count", contracts.size());

    return "pms/contract/contractListBudget";
}

这里把原来Dao中的List<?>都改成了Set,直接就等于去重了。页面只要使用项目列表的页面稍加修改:

<main class="container">

    <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.absoluteUrl()}"
                                                               class="link-secondary">[[${project.projectName}]]</a>
            </li>
            <li class="breadcrumb-item" aria-current="page"><a href="/pms/budget/detail"
                                                               th:href="${'/pms/budget/' + project.getId() +'/detail/'+ budget.getId()}"
                                                               class="link-secondary">[[${budget.budgetName}]]</a></li>
            <li class="breadcrumb-item" aria-current="page"><a href="/pms/project/list"
                                                               th:href="${budget.contractListUrl()}"
                                                               class="link-secondary">合同列表</a>
            </li>
        </ol>
    </nav>
    <div class="row py-1" >
        <div class="col-sm-4"></div>
        <div th:if="${created}" class="text-center alert alert-success col-12 col-sm-4" role="alert">
            [[${created}]]
        </div>
        <div th:if="${updated}" class="text-center alert alert-success col-12 col-sm-4" role="alert">
            [[${updated}]]
        </div>
        <div th:if="${deleted}" class="text-center alert alert-success col-12 col-sm-4" role="alert">
            [[${deleted}]]
        </div>
        <div class="col-sm-4"></div>
    </div>
    <p>
        <a class="btn btn-primary" href="/pms/project/add" th:href="${project.addContractUrl()}"><i class="fas fa-plus"></i>&nbsp;新增合同</a>
    </p>
    <table class="table table-hover" th:if="${count != 0}">
        <thead>
        <tr>
            <th>合同编号</th>
            <th>合同名称</th>
            <th>合同总价</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="contract, control:${contracts}">
            <td th:text="${contract.number}"></td>
            <td th:text="${contract.name}"></td>
            <td th:text="${#numbers.formatDecimal(contract.totalPrice,0,'COMMA',2,'POINT')}"></td>
        </tr>
        </tbody>
    </table>

</main>

做完上述步骤后,记得到项目和预算条目的详情页,将功能导航中的功能链接修改成实际可用的链接,这样就写好了两种列出合同的方式。

LICENSED UNDER CC BY-NC-SA 4.0
Comment