feat(sip): 添加订单财务归档状态管理功能

- 在 ProjectOrderInfo 实体中新增 financeStatus 字段,用于标识订单是否完结
- 新增订单财务页面 orderFinance.html,支持按财务状态筛选订单
- 在 IProjectOrderInfoService 接口中添加 updateFinance 方法- 在 ProjectOrderInfoController 中新增财务状态更新接口 /finance/update- 更新 ProjectOrderInfoMapper.xml,支持 financeStatus 的查询与更新
- 导出 Excel 功能增加归档时间字段展示
- 增加财务状态操作按钮,允许用户手动完结订单
- 修复执行单截止时间筛选条件错误的问题
- 调整导出数据列索引,确保归档时间正确显示
dev_1.0.0
chenhao 2025-10-28 15:08:30 +08:00
parent 256ef27913
commit 8b2372db42
6 changed files with 420 additions and 4 deletions

View File

@ -0,0 +1,383 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('订单管理列表')"/>
</head>
<style>
.select-list li p, .select-list li label:not(.radio-box) {
width: 80px;
}
.bootstrap-table table {
table-layout: fixed;
}
.sortBox {
display: flex;
float: right;
flex-direction: column;
gap: 0;
height: 20px;
justify-content: center;
margin-right: 30px;
}
.sortBox div {
font-size: 10px;
transform: scale(1.2, 1);
cursor: pointer;
color: #bbb;
}
.sortBox .timeAction {
color: #000;
}
.timeSearch {
display: flex;
gap: 20px;
align-items: center;
}
</style>
<body class="gray-bg">
<div class="container-div">
<!-- <div th:replace="layout/product-list::product()"></div>-->
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div id="content"></div>
<div class="select-list">
<ul>
<li>
<label>项目编号:</label>
<input type="text" name="projectCode" placeholder="项目编号"/>
</li>
<li>
<label>项目名称:</label>
<input type="text" name="projectName" placeholder="项目名称"/>
</li>
<li>
<label>合同编号:</label>
<input type="text" name="orderCode" placeholder="合同编号"/>
</li>
<li>
<label>最终客户:</label>
<input type="text" name="customerName" placeholder="最终客户"/>
</li>
<li>
<label>订单状态:</label>
<select name="orderStatus" class="form-control"
th:with="type=${@dict.getType('order_status')}">
<option value="">请选择</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}"
th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
<label>代表处:</label>
<input type="text" name="agentName" placeholder="代表处"/>
</li>
<li>
<label>汇智负责人:</label>
<input type="text" name="dutyName" placeholder="项目负责人"/>
</li>
<li>
<label>进货商:</label>
<input type="text" name="partnerName" placeholder="进货商"/>
</li>
<li>
<label>完结状态:</label>
<select name="financeStatus" value="0">
<option value="">全部</option>
<option value="0">未完结</option>
<option value="1">已完结</option>
</select>
</li>
<li class="timeSearch" style="width: 80%">
<div>
<label>时间选择:</label>
<select name="timeType" onchange="changeTimeType()" value="0">
<option value="0">到货时间</option>
<option value="1">下单时间</option>
<option value="2">执行单截止时间</option>
<option value="3">归档时间</option>
</select>
</div>
<div class="timeSearch">
<input name="deliveryTimeStart" type="text" class="input-sm form-control"
id="laydate-startTime"
placeholder="yyyy-MM-dd"/>
<span></span>
<input name="deliveryTimeEnd" type="text" class="input-sm form-control"
id="laydate-endTime"
placeholder="yyyy-MM-dd"/>
</div>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i
class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i
class="fa fa-refresh"></i>&nbsp;重置</a>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="project:order:export">
<i class="fa fa-download"></i> 导出
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer"/>
<th:block th:include="include :: bootstrap-table-fixed-columns-js"/>
<th:block th:include="include :: jquery-cxselect-js"/>
<script th:inline="javascript">
var editFlag = [[${@permission.hasPermi('project:order:edit')}]];
var removeFlag = [[${@permission.hasPermi('project:order:remove')}]];
var prefix = ctx + "project/order";
function changeTimeType() {
let timeType = $("[name='timeType']").val()
if (timeType == 0) {
$('#laydate-startTime').attr('name', 'deliveryTimeStart')
$('#laydate-endTime').attr('name', 'deliveryTimeEnd')
} else if (timeType == 1) {
$('#laydate-startTime').attr('name', 'estimatedOrderTimeStart')
$('#laydate-endTime').attr('name', 'estimatedOrderTimeEnd')
} else if (timeType == 2) {
$('#laydate-startTime').attr('name', 'orderEndTimeStart')
$('#laydate-endTime').attr('name', 'orderEndTimeEnd')
} else if (timeType == 3) {
$('#laydate-startTime').attr('name', 'approveTimeStart')
$('#laydate-endTime').attr('name', 'approveTimeEnd')
}
}
function viewDetail(id) {
$.modal.openFull("订单详情", ctx + "project/order/view/" + id)
}
function viewApproveLog(id) {
$.modal.open("订单详情", ctx + "project/order/approveLog/" + id)
}
function viewProjectDetail(id) {
$.modal.openFull("项目详情", ctx + "sip/project/view/" + id)
}
function updateFinanceStatus(id, status) {
$.ajax({
type: "post",
url: prefix + "/finance/update",
data: {
id: id,
financeStatus: status
},
success: function (result) {
if (result.code == web_status.SUCCESS) {
$.modal.msgSuccess("操作成功");
$.table.refresh();
} else {
$.modal.msgError(result.msg);
}
}
});
}
$(function () {
// $('#content').load(ctx + 'project/order/add');
var urlChina = '/cnarea/select';
$.cxSelect.defaults.url = urlChina;
// $.cxSelect.defaults.jsonSpace = 'data';
$('#element1').cxSelect({
selects: ['province', 'city'],
nodata: 'none'
});
var options = {
url: prefix + "/list",
createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
modalName: "订单管理",
fixedColumns: true,
sortable: true,
fixedRightNumber: 1,
columns: [{
checkbox: true
},
{
field: 'id',
title: '',
visible: false
},
{
field: 'projectCode',
title: '项目编号',
width: 100
},
{
field: 'projectName',
title: '项目名称',
width: 300,
formatter: function (value, row, index) {
return '<a href="javascript:viewProjectDetail(' + row.projectId + ')">' + value + '</a>';
}
},
{
field: 'orderCode',
title: '合同编号',
width: 200,
formatter: function (value, row, index) {
return '<a href="javascript:viewDetail(' + row.id + ')">' + value + '</a>';
}
},
{
field: 'customerName',
title: '最终客户',
width: 200
},
{
field: 'actualPurchaseAmount',
title: '金额(¥)',
sortable: true,
width: 100,
formatter: function (value, row, index) {
let actualPurchaseAmount = value ? formatAmountNumber(value) : '';
let shipmentAmount = row.shipmentAmount ? formatAmountNumber(row.shipmentAmount) : '';
return (row.orderStatus == 1 || row.orderStatus == 2) ? actualPurchaseAmount : shipmentAmount;
}
},
{
field: 'orderStatus',
title: '订单状态',
width: 100,
formatter: function (value, row, index) {
return $.table.selectDictLabel([[${@dict.getType('order_status')}]], value);
}
},
{
field: 'agentName',
title: '代表处',
width: 100
},
{
field: 'dutyName',
title: '汇智负责人',
width: 100
},
{
field: '',
title: '物流状态',
width: 100
},
{
field: 'partnerName',
title: '进货商',
width: 200
},
{
field: 'deliveryTime',
title: '到货时间',
sortable: true,
width: 200
},
{
field: 'estimatedOrderTime',
title: '下单时间',
sortable: true,
width: 200
},
{
field: 'orderEndTime',
title: '执行单截止时间',
sortable: true,
width: 200
},
{
field: 'approveTime',
title: '归档时间',
sortable: true,
width: 200
},
{
title: '操作',
align: 'center',
width: 200,
formatter: function (value, row, index) {
var actions = [];
console.log(row.financeStatus)
console.log(row.financeStatus != '1')
if (row.financeStatus != '1') {
actions.push('<a class="btn btn-success btn-xs " href="javascript:void(0)" onclick="updateFinanceStatus(\'' + row.id + '\',\'' + 1 + '\',)"><i class="fa fa-edit"></i>完结</a> ');
}
return actions.join('');
}
}]
};
$.table.init(options);
layui.use('laydate', function () {
var laydate = layui.laydate;
var startDate = laydate.render({
elem: '#laydate-startTime',
max: $('#laydate-endTime').val(),
theme: 'molv',
trigger: 'click',
done: function (value, date) {
// 结束时间大于开始时间
if (value !== '') {
endDate.config.min.year = date.year;
endDate.config.min.month = date.month - 1;
endDate.config.min.date = date.date;
} else {
endDate.config.min.year = '';
endDate.config.min.month = '';
endDate.config.min.date = '';
}
}
});
var endDate = laydate.render({
elem: '#laydate-endTime',
min: $('#laydate-startTime').val(),
theme: 'molv',
trigger: 'click',
done: function (value, date) {
// 开始时间小于结束时间
if (value !== '') {
startDate.config.max.year = date.year;
startDate.config.max.month = date.month - 1;
startDate.config.max.date = date.date;
} else {
startDate.config.max.year = '';
startDate.config.max.month = '';
startDate.config.max.date = '';
}
}
});
})
});
</script>
</body>
</html>

View File

@ -93,6 +93,12 @@ public class ProjectOrderInfoController extends BaseController
return prefix + "/order";
}
@RequiresPermissions("project:order:view")
@GetMapping("/finance")
public String orderFinance() {
return prefix + "/orderFinance";
}
@GetMapping("/approve/{id}")
public String approve(@PathVariable("id") Long id, ModelMap mmap) {
mmap.put("approve", true);
@ -150,6 +156,18 @@ public class ProjectOrderInfoController extends BaseController
return getDataTable(list);
}
/**
*
*/
@Log(title = "订单管理", businessType = BusinessType.UPDATE)
@PostMapping("/finance/update")
@ResponseBody
public AjaxResult update(ProjectOrderInfo projectOrderInfo) {
projectOrderInfoService.updateFinance(projectOrderInfo);
return AjaxResult.success();
}
/**
*
*/

View File

@ -265,6 +265,9 @@ public class ProjectOrderInfo extends BaseEntity {
*/
private String paymentDescription;
// 财务归档状态 0:未完结 1:已完结
private String financeStatus;
private List<ProjectOrderFileLog> contractFileList;
private List<ProjectOrderFileLog> configFileList;
private Map<String, List<ProjectOrderFileLog>> contractTableData;

View File

@ -98,4 +98,6 @@ public interface IProjectOrderInfoService
byte[] exportContractTemplate(ProjectOrderInfo orderInfo);
List<ProjectOrderInfo> listByCodeList(List<String> businessKeyList);
void updateFinance(ProjectOrderInfo projectOrderInfo);
}

View File

@ -805,6 +805,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
// headerList.add(Collections.singletonList("其他特别说明"));
// headerList.add(Collections.singletonList("订单状态"));
headerList.add(Collections.singletonList("执行单截至时间"));
headerList.add(Collections.singletonList("归档时间"));
headerList.add(Collections.singletonList("WS瘦授权软件数量-3130A6LC"));
headerList.add(Collections.singletonList("WS瘦授权软件金额"));
headerList.add(Collections.singletonList("WS瘦授权软件税率"));
@ -953,7 +954,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
totalPrice = processProducts(deployList, maxDeployService, row, totalPrice);
//添加维保
totalPrice = processProducts(maintenanceList, maxMaintenanceService, row, totalPrice);
int insertIndex=20;
int insertIndex=21;
row.add(insertIndex++, wssDto.getQuantity());
row.add(insertIndex++, wssDto.getAllPrice());
row.add(insertIndex++, wssDto.getTaxRate());
@ -1045,6 +1046,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
// row.add(info.getPartnerEmail());
row.add(info.getPartnerPhone());
row.add(DateUtil.format(info.getOrderEndTime(), "yyyy-MM-dd"));
row.add(DateUtil.format(info.getApproveTime(), "yyyy-MM-dd HH:mm:ss"));
// row.add(info.getRemark());
// row.add(DictUtils.getDictLabel("order_status", info.getOrderStatus()));
}
@ -1462,6 +1464,12 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
return projectOrderInfoMapper.listByCodeList(businessKeyList);
}
@Override
public void updateFinance(ProjectOrderInfo projectOrderInfo) {
projectOrderInfoMapper.updateProjectOrderInfo(projectOrderInfo);
}
private void replaceTextInDocument(XWPFDocument document, ProjectOrderInfo orderInfo) {
// 替换段落中的文本
for (XWPFParagraph paragraph : document.getParagraphs()) {

View File

@ -41,7 +41,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<sql id="selectProjectOrderInfoVo">
select id, project_id,province, city, business_person, business_email, business_phone, order_code, currencyType,
shipment_amount, actual_purchase_amount, order_end_time, delivery_time, company_delivery, notifier,
shipment_amount, actual_purchase_amount, order_end_time, delivery_time, company_delivery, notifier,finance_status,
notifier_email, notifier_phone, duty, duty_email, duty_phone, order_channel, partner_code, supplier,notifier_address,
remark, order_status, create_by, create_time, update_by, update_time,version_code,process_type,process_template,discount_fold,
delivery_status,sign_status,outer_status,approve_time,payment_method,payment_ratio,payment_description
@ -53,7 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
t1.shipment_amount, t1.actual_purchase_amount, t1.order_end_time, t1.delivery_time, t1.company_delivery, t1.notifier,
t1.notifier_email, t1.notifier_phone, t1.duty, t1.duty_email, t1.duty_phone, t1.order_channel, t1.partner_code, t1.supplier,
t1.remark, t1.order_status, t1.create_by, t1.create_time, t1.update_by, t1.update_time,t1.partner_user_name,t1.partner_email
,t1.partner_phone,t1.version_code,t1.process_type,t1.process_template,t1.discount_fold,t1.notifier_address,
,t1.partner_phone,t1.version_code,t1.process_type,t1.process_template,t1.discount_fold,t1.notifier_address,t1.finance_status,
t1.delivery_status,t1.sign_status,t1.outer_status,t1.approve_time,t1.payment_method,t1.payment_ratio,t1.payment_description
,t2.project_code,t2.project_name,t2.province,t2.customer_name,t2.customer_code,t2.industry_type,t2.bg_property,t2.agent_code,t2.estimated_order_time
,t2.customer_phone,t2.customer_user_name,t2.agent_code,t2.customer_code,t2.partner_name project_partner_name
@ -82,6 +82,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
concat('%',#{customerName},'%')
</if>
<if test="agentName != null and agentName!=''">and t4.agent_name like concat('%',#{agentName},'%')</if>
<if test="financeStatus != null and financeStatus!=''">and t1.finance_status =#{financeStatus}</if>
<if test="province != null and province != ''">and t1.province = #{province}</if>
<if test="city != null and city != ''">and t1.city = #{city}</if>
<if test="businessPerson != null and businessPerson != ''">and t1.business_person = #{businessPerson}</if>
@ -154,7 +155,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and t1.approve_time between date_format(#{approveTimeStart}, '%Y-%m-%d 00:00:00') and
date_format(#{approveTimeEnd}, '%Y-%m-%d 23:59:59')
</when>
<when test="deliveryTimeStart != null">
<when test="approveTimeStart != null">
and t1.approve_time <![CDATA[ >= ]]> date_format(#{approveTimeStart}, '%Y-%m-%d 00:00:00')
</when>
<when test="approveTimeEnd != null">
@ -498,6 +499,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="paymentMethod != null and paymentMethod != ''">payment_method = #{paymentMethod},</if>
<if test="paymentRatio != null">payment_ratio = #{paymentRatio},</if>
<if test="paymentDescription != null and paymentDescription != ''">payment_description = #{paymentDescription},</if>
<if test="financeStatus != null and financeStatus != ''">finance_status = #{financeStatus},</if>
</trim>
where id = #{id}
</update>