feat(project): 优化项目管理和收款单功能

- 在application-prod.yml中配置flowable数据库模式更新设置
- 为项目信息表格的收藏和会审列添加固定右侧显示功能
- 修改订单生成逻辑,添加会审状态检查和权限验证
- 实现项目会审状态修改时的订单存在性验证
- 添加收款单按编码查询的接口和实现
- 重构收款单审批回调逻辑,支持多实例审批流程
- 更新项目生成订单权限判断逻辑,移除会审状态依赖
- 在订单创建时添加项目会审状态验证机制
dev_1.0.0
chenhao 2026-01-07 15:39:11 +08:00
parent b1cbbec237
commit 97bcc1ac0a
6 changed files with 134 additions and 47 deletions

View File

@ -202,12 +202,12 @@
<span>{{ parseTime(scope.row.lastWorkUpdateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="收藏" align="center" prop="collect" width="60">
<el-table-column label="收藏" align="center" prop="collect" width="60" fixed="right">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.collect" true-label="1" false-label="0" @change="handleCollectChange(scope.row)" />
</template>
</el-table-column>
<el-table-column label="会审" align="center" prop="jointTrial" width="60">
<el-table-column label="会审" align="center" prop="jointTrial" width="60" fixed="right">
<template slot-scope="scope">
<el-checkbox v-if="!canUpdateJoinTrial" :value="scope.row.jointTrial === '1'" @change="()=>{ $modal.msgError('无权限修改');return false;}" />
<el-checkbox v-else v-model="scope.row.jointTrial" true-label="1" false-label="0" @change="handleJoinTrialChange(scope.row)"/>
@ -226,8 +226,8 @@
size="mini"
type="text"
icon="el-icon-refresh"
@click="openOrder(scope.row.id, scope.row.canGenerate)"
:disabled="!scope.row.canGenerate || scope.row.jointTrial !== '1'"
@click="openOrder(scope.row.id, scope.row.canGenerate, scope.row.jointTrial)"
:disabled="!scope.row.canGenerate "
v-hasPermi="['sip:project:add']"
>生成订单</el-button>
<el-button
@ -481,7 +481,11 @@ export default {
}
},
/** 生成订单 */
openOrder(id, canGenerate) {
openOrder(id, canGenerate,jointTrial) {
if (jointTrial!=='1') {
this.$modal.alertWarning("请联系产品经理和售后团队进行会审后再生成订单");
return;
}
if (!canGenerate) {
this.$modal.alertWarning("该项目已存在订单");
return;
@ -509,6 +513,10 @@ export default {
/** 项目会审状态修改 */
handleJoinTrialChange(row) {
if (row.jointTrial === '0'){
if (!row.canGenerate){
this.$modal.alertWarning("该项目已存在订单,无法取消会审");
return;
}
this.$modal.confirm('是否确认取消会审?').then(function() {
let params={
"id":row.id,
@ -517,7 +525,6 @@ export default {
}
editJoinTrial(params).then(response => {
this.$modal.msgSuccess("取消成功");
})
}).catch((err)=>{
row.jointTrial = row.jointTrial === '1' ? '0' : '1';

View File

@ -96,6 +96,14 @@ public class OmsReceiptBillController extends BaseController {
, OmsReceiptBill::getReceiptBillCode, (a, b) -> a.setApproveNode(b.get(a.getReceiptBillCode())));
return AjaxResult.success(data);
}
@GetMapping(value = "/code/{code}")
public AjaxResult getInfoByCode(@PathVariable("code") String receiptBillCode) {
OmsReceiptBill data = omsReceiptBillService.getInfoByCode(receiptBillCode);
// todoService.fillApproveNode(Collections.singletonList(data),
// Arrays.asList(processConfig.getDefinition().getFinanceReceiptApprove(), processConfig.getDefinition().getFinanceReceiptRefound())
// , OmsReceiptBill::getReceiptBillCode, (a, b) -> a.setApproveNode(b.get(a.getReceiptBillCode())));
return AjaxResult.success(data);
}

View File

@ -68,6 +68,8 @@ public interface IOmsReceiptBillService {
List<OmsReceiptBill> listApproved(OmsReceiptBill omsReceiptBill);
AjaxResult revoke(OmsReceiptBill omsReceiptBill);
OmsReceiptBill getInfoByCode(String receiptBillCode);
}

View File

@ -548,6 +548,20 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService, TodoCo
return AjaxResult.success("撤销成功");
}
@Override
public OmsReceiptBill getInfoByCode(String receiptBillCode) {
OmsReceiptBill receiptBill = omsReceiptBillMapper.queryByCode(receiptBillCode);
if (receiptBill == null){
return null;
}
List<ReceiptDetailDTO> receiptDetailDTOS = omsReceivableReceiptDetailService.listReceivableByReceiptBillCode(receiptBill.getReceiptBillCode());
receiptBill.setDetailDTOList(receiptDetailDTOS);
List<OmsFinAttachment> list = attachmentService.list(Collections.singletonList(receiptBill.getId()), OmsFinAttachment.RelatedBillTypeEnum.RECEIPT.getCode());
Optional<OmsFinAttachment> first = list.stream().filter(item -> !"2".equals(item.getDelFlag())).max((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()));
receiptBill.setAttachment(first.orElse(null));
return receiptBill;
}
@Override
public Object todoDetail(String businessKey, String processKey, String todoId) {
@ -585,45 +599,45 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService, TodoCo
omsReceiptBillMapper.update(updateBill);
}
}else{
if (todo.getProcessKey().equals(processConfig.getDefinition().getFinanceReceiptApprove()) && taskName.startsWith("财务")){
//处理收款审批
OmsReceiptBill updateBill = new OmsReceiptBill();
updateBill.setId(receiptBill.getId());
updateBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
updateBill.setActualReceiptTime(DateUtils.getNowDate());
updateBill.setApproveTime(DateUtils.getNowDate());
updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.PAYMENT.getCode());
if (receiptBill.getReceiptBillType().equals(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode())){
updateBill.setRemainingAmount(receiptBill.getTotalPriceWithTax());
}
omsReceiptBillMapper.update(updateBill);
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode());
receivableBillService.updateReceiptAmount(omsReceivableReceiptDetailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).collect(Collectors.toList()));
if (!receiptBill.getReceiptBillType().equals(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode())) {
//审批完成后需要自动核销 因为审批时已经上传附件
WriteOffReceiptRequestDto writeOffRequestDto = new WriteOffReceiptRequestDto();
writeOffRequestDto.setReceiptBillId(receiptBill.getId());
writeOffRequestDto.setDetailList(omsReceivableReceiptDetailList);
writeOffRequestDto.setPartnerCode(receiptBill.getPartnerCode());
writeOffRequestDto.setPartnerName(receiptBill.getPartnerName());
writeOffRequestDto.setRemark(StrUtil.format("{}自动核销数据:{}", DateUtils.getTime(), receiptBill.getReceiptBillCode()));
// 新增核销记录
omsReceivableWriteOffService.autoWriteOff(writeOffRequestDto);
}
}else if(todo.getProcessKey().equals(processConfig.getDefinition().getFinanceReceiptRefound()) && taskName.startsWith("公司领导")){
//处理退款审批
OmsReceiptBill updateBill = new OmsReceiptBill();
updateBill.setId(receiptBill.getId());
updateBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
updateBill.setApproveTime(DateUtils.getNowDate());
updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.REFUNDED.getCode());
omsReceiptBillMapper.update(updateBill);
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode());
receivableBillService.updateReceiptAmount(omsReceivableReceiptDetailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).collect(Collectors.toList()));
}
// if (todo.getProcessKey().equals(processConfig.getDefinition().getFinanceReceiptApprove()) && taskName.startsWith("财务")){
// //处理收款审批
// OmsReceiptBill updateBill = new OmsReceiptBill();
// updateBill.setId(receiptBill.getId());
// updateBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
// updateBill.setActualReceiptTime(DateUtils.getNowDate());
// updateBill.setApproveTime(DateUtils.getNowDate());
// updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.PAYMENT.getCode());
// if (receiptBill.getReceiptBillType().equals(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode())){
// updateBill.setRemainingAmount(receiptBill.getTotalPriceWithTax());
// }
// omsReceiptBillMapper.update(updateBill);
// List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode());
// receivableBillService.updateReceiptAmount(omsReceivableReceiptDetailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).collect(Collectors.toList()));
// if (!receiptBill.getReceiptBillType().equals(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode())) {
// //审批完成后需要自动核销 因为审批时已经上传附件
// WriteOffReceiptRequestDto writeOffRequestDto = new WriteOffReceiptRequestDto();
// writeOffRequestDto.setReceiptBillId(receiptBill.getId());
// writeOffRequestDto.setDetailList(omsReceivableReceiptDetailList);
// writeOffRequestDto.setPartnerCode(receiptBill.getPartnerCode());
// writeOffRequestDto.setPartnerName(receiptBill.getPartnerName());
// writeOffRequestDto.setRemark(StrUtil.format("{}自动核销数据:{}", DateUtils.getTime(), receiptBill.getReceiptBillCode()));
// // 新增核销记录
// omsReceivableWriteOffService.autoWriteOff(writeOffRequestDto);
// }
//
//
//
// }else if(todo.getProcessKey().equals(processConfig.getDefinition().getFinanceReceiptRefound()) && taskName.startsWith("公司领导")){
// //处理退款审批
// OmsReceiptBill updateBill = new OmsReceiptBill();
// updateBill.setId(receiptBill.getId());
// updateBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
// updateBill.setApproveTime(DateUtils.getNowDate());
// updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.REFUNDED.getCode());
// omsReceiptBillMapper.update(updateBill);
// List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode());
// receivableBillService.updateReceiptAmount(omsReceivableReceiptDetailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).collect(Collectors.toList()));
// }
}
@ -637,6 +651,52 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService, TodoCo
@Override
public boolean multiInstanceApproveCallback(String activityName, ProcessInstance processInstance) {
Map<String, Object> processVariables = processInstance.getProcessVariables();
Integer approveBtn = (Integer) processVariables.get("approveBtn");
if (approveBtn == null || approveBtn!=1){
return TodoCommonTemplate.super.multiInstanceApproveCallback(activityName, processInstance);
}
String flowBusinessKey = processInstance.getBusinessKey();
OmsReceiptBill receiptBill = omsReceiptBillMapper.queryByCode(flowBusinessKey);
if (processInstance.getProcessDefinitionKey().equals(processConfig.getDefinition().getFinanceReceiptApprove()) && activityName.startsWith("财务")){
//处理收款审批
OmsReceiptBill updateBill = new OmsReceiptBill();
updateBill.setId(receiptBill.getId());
updateBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
updateBill.setActualReceiptTime(DateUtils.getNowDate());
updateBill.setApproveTime(DateUtils.getNowDate());
updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.PAYMENT.getCode());
if (receiptBill.getReceiptBillType().equals(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode())){
updateBill.setRemainingAmount(receiptBill.getTotalPriceWithTax());
}
omsReceiptBillMapper.update(updateBill);
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode());
receivableBillService.updateReceiptAmount(omsReceivableReceiptDetailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).collect(Collectors.toList()));
if (!receiptBill.getReceiptBillType().equals(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode())) {
//审批完成后需要自动核销 因为审批时已经上传附件
WriteOffReceiptRequestDto writeOffRequestDto = new WriteOffReceiptRequestDto();
writeOffRequestDto.setReceiptBillId(receiptBill.getId());
writeOffRequestDto.setDetailList(omsReceivableReceiptDetailList);
writeOffRequestDto.setPartnerCode(receiptBill.getPartnerCode());
writeOffRequestDto.setPartnerName(receiptBill.getPartnerName());
writeOffRequestDto.setRemark(StrUtil.format("{}自动核销数据:{}", DateUtils.getTime(), receiptBill.getReceiptBillCode()));
// 新增核销记录
omsReceivableWriteOffService.autoWriteOff(writeOffRequestDto);
}
}else if(processInstance.getProcessDefinitionKey().equals(processConfig.getDefinition().getFinanceReceiptRefound()) && activityName.startsWith("公司领导")){
//处理退款审批
OmsReceiptBill updateBill = new OmsReceiptBill();
updateBill.setId(receiptBill.getId());
updateBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
updateBill.setApproveTime(DateUtils.getNowDate());
updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.REFUNDED.getCode());
omsReceiptBillMapper.update(updateBill);
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode());
receivableBillService.updateReceiptAmount(omsReceivableReceiptDetailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).collect(Collectors.toList()));
}
return TodoCommonTemplate.super.multiInstanceApproveCallback(activityName, processInstance);
}
}

View File

@ -158,7 +158,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
if (customerInfo != null) {
info.setCustomerAddress(customerInfo.getAddress());
}
info.setCanGenerate(orderInfoMap.get(info.getId()) == null && "1".equals(info.getJointTrial()));
info.setCanGenerate(orderInfoMap.get(info.getId()) == null);
if (info.getLastWorkUpdateTime() != null) {
LocalDate localDate = info.getLastWorkUpdateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
Period between = Period.between(localDate, now);
@ -604,7 +604,13 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
@Override
public int editJoinTrial(ProjectInfo projectInfo) {
return projectInfoMapper.updateProjectInfo(projectInfo);
if ("0".equals(projectInfo.getJointTrial())){
List<ProjectOrderInfo> projectOrderInfos = orderInfoService.selectProjectOrderInfoByProjectId(Collections.singletonList(projectInfo.getId()));
if (CollUtil.isNotEmpty(projectOrderInfos)){
throw new ServiceException("已生成项目,无法取消会审");
}
}
return projectInfoMapper.updateProjectInfo(projectInfo);
}
private List<ProjectInfo> fetchProjectInfos(ProjectInfo projectInfo) {

View File

@ -294,6 +294,10 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
if (projectOrderInfo.getProjectId() == null) {
throw new ServiceException("请选择项目");
}
ProjectInfo projectInfo = projectInfoMapper.selectProjectInfoById(projectOrderInfo.getProjectId());
if (projectInfo == null|| !"1".equals(projectInfo.getJointTrial())){
throw new ServiceException("请进行项目会审");
}
List<ProjectOrderInfo> projectOrderInfos = this.selectProjectOrderInfoByProjectId(Collections.singletonList(projectOrderInfo.getProjectId()));
if (CollUtil.isNotEmpty(projectOrderInfos)) {
throw new ServiceException("该项目存在订单流转,无法添加");