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> <span>{{ parseTime(scope.row.lastWorkUpdateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template> </template>
</el-table-column> </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"> <template slot-scope="scope">
<el-checkbox v-model="scope.row.collect" true-label="1" false-label="0" @change="handleCollectChange(scope.row)" /> <el-checkbox v-model="scope.row.collect" true-label="1" false-label="0" @change="handleCollectChange(scope.row)" />
</template> </template>
</el-table-column> </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"> <template slot-scope="scope">
<el-checkbox v-if="!canUpdateJoinTrial" :value="scope.row.jointTrial === '1'" @change="()=>{ $modal.msgError('无权限修改');return false;}" /> <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)"/> <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" size="mini"
type="text" type="text"
icon="el-icon-refresh" icon="el-icon-refresh"
@click="openOrder(scope.row.id, scope.row.canGenerate)" @click="openOrder(scope.row.id, scope.row.canGenerate, scope.row.jointTrial)"
:disabled="!scope.row.canGenerate || scope.row.jointTrial !== '1'" :disabled="!scope.row.canGenerate "
v-hasPermi="['sip:project:add']" v-hasPermi="['sip:project:add']"
>生成订单</el-button> >生成订单</el-button>
<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) { if (!canGenerate) {
this.$modal.alertWarning("该项目已存在订单"); this.$modal.alertWarning("该项目已存在订单");
return; return;
@ -509,6 +513,10 @@ export default {
/** 项目会审状态修改 */ /** 项目会审状态修改 */
handleJoinTrialChange(row) { handleJoinTrialChange(row) {
if (row.jointTrial === '0'){ if (row.jointTrial === '0'){
if (!row.canGenerate){
this.$modal.alertWarning("该项目已存在订单,无法取消会审");
return;
}
this.$modal.confirm('是否确认取消会审?').then(function() { this.$modal.confirm('是否确认取消会审?').then(function() {
let params={ let params={
"id":row.id, "id":row.id,
@ -517,7 +525,6 @@ export default {
} }
editJoinTrial(params).then(response => { editJoinTrial(params).then(response => {
this.$modal.msgSuccess("取消成功"); this.$modal.msgSuccess("取消成功");
}) })
}).catch((err)=>{ }).catch((err)=>{
row.jointTrial = row.jointTrial === '1' ? '0' : '1'; 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()))); , OmsReceiptBill::getReceiptBillCode, (a, b) -> a.setApproveNode(b.get(a.getReceiptBillCode())));
return AjaxResult.success(data); 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); List<OmsReceiptBill> listApproved(OmsReceiptBill omsReceiptBill);
AjaxResult revoke(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("撤销成功"); 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 @Override
public Object todoDetail(String businessKey, String processKey, String todoId) { public Object todoDetail(String businessKey, String processKey, String todoId) {
@ -585,45 +599,45 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService, TodoCo
omsReceiptBillMapper.update(updateBill); omsReceiptBillMapper.update(updateBill);
} }
}else{ }else{
if (todo.getProcessKey().equals(processConfig.getDefinition().getFinanceReceiptApprove()) && taskName.startsWith("财务")){ // if (todo.getProcessKey().equals(processConfig.getDefinition().getFinanceReceiptApprove()) && taskName.startsWith("财务")){
//处理收款审批 // //处理收款审批
OmsReceiptBill updateBill = new OmsReceiptBill(); // OmsReceiptBill updateBill = new OmsReceiptBill();
updateBill.setId(receiptBill.getId()); // updateBill.setId(receiptBill.getId());
updateBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode()); // updateBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
updateBill.setActualReceiptTime(DateUtils.getNowDate()); // updateBill.setActualReceiptTime(DateUtils.getNowDate());
updateBill.setApproveTime(DateUtils.getNowDate()); // updateBill.setApproveTime(DateUtils.getNowDate());
updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.PAYMENT.getCode()); // updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.PAYMENT.getCode());
if (receiptBill.getReceiptBillType().equals(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode())){ // if (receiptBill.getReceiptBillType().equals(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode())){
updateBill.setRemainingAmount(receiptBill.getTotalPriceWithTax()); // updateBill.setRemainingAmount(receiptBill.getTotalPriceWithTax());
} // }
omsReceiptBillMapper.update(updateBill); // omsReceiptBillMapper.update(updateBill);
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode()); // List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode());
receivableBillService.updateReceiptAmount(omsReceivableReceiptDetailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).collect(Collectors.toList())); // receivableBillService.updateReceiptAmount(omsReceivableReceiptDetailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).collect(Collectors.toList()));
if (!receiptBill.getReceiptBillType().equals(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode())) { // if (!receiptBill.getReceiptBillType().equals(OmsReceiptBill.ReceiptBillTypeEnum.PRE_RECEIPT.getCode())) {
//审批完成后需要自动核销 因为审批时已经上传附件 // //审批完成后需要自动核销 因为审批时已经上传附件
WriteOffReceiptRequestDto writeOffRequestDto = new WriteOffReceiptRequestDto(); // WriteOffReceiptRequestDto writeOffRequestDto = new WriteOffReceiptRequestDto();
writeOffRequestDto.setReceiptBillId(receiptBill.getId()); // writeOffRequestDto.setReceiptBillId(receiptBill.getId());
writeOffRequestDto.setDetailList(omsReceivableReceiptDetailList); // writeOffRequestDto.setDetailList(omsReceivableReceiptDetailList);
writeOffRequestDto.setPartnerCode(receiptBill.getPartnerCode()); // writeOffRequestDto.setPartnerCode(receiptBill.getPartnerCode());
writeOffRequestDto.setPartnerName(receiptBill.getPartnerName()); // writeOffRequestDto.setPartnerName(receiptBill.getPartnerName());
writeOffRequestDto.setRemark(StrUtil.format("{}自动核销数据:{}", DateUtils.getTime(), receiptBill.getReceiptBillCode())); // writeOffRequestDto.setRemark(StrUtil.format("{}自动核销数据:{}", DateUtils.getTime(), receiptBill.getReceiptBillCode()));
// 新增核销记录 // // 新增核销记录
omsReceivableWriteOffService.autoWriteOff(writeOffRequestDto); // omsReceivableWriteOffService.autoWriteOff(writeOffRequestDto);
} // }
//
//
//
}else if(todo.getProcessKey().equals(processConfig.getDefinition().getFinanceReceiptRefound()) && taskName.startsWith("公司领导")){ // }else if(todo.getProcessKey().equals(processConfig.getDefinition().getFinanceReceiptRefound()) && taskName.startsWith("公司领导")){
//处理退款审批 // //处理退款审批
OmsReceiptBill updateBill = new OmsReceiptBill(); // OmsReceiptBill updateBill = new OmsReceiptBill();
updateBill.setId(receiptBill.getId()); // updateBill.setId(receiptBill.getId());
updateBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode()); // updateBill.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
updateBill.setApproveTime(DateUtils.getNowDate()); // updateBill.setApproveTime(DateUtils.getNowDate());
updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.REFUNDED.getCode()); // updateBill.setReceiptStatus(OmsReceiptBill.ReceiptStatusEnum.REFUNDED.getCode());
omsReceiptBillMapper.update(updateBill); // omsReceiptBillMapper.update(updateBill);
List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode()); // List<OmsReceivableReceiptDetail> omsReceivableReceiptDetailList = omsReceivableReceiptDetailService.listByReceiptBillCode(receiptBill.getReceiptBillCode());
receivableBillService.updateReceiptAmount(omsReceivableReceiptDetailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).collect(Collectors.toList())); // receivableBillService.updateReceiptAmount(omsReceivableReceiptDetailList.stream().map(OmsReceivableReceiptDetail::getReceivableBillId).collect(Collectors.toList()));
} // }
} }
@ -637,6 +651,52 @@ public class OmsReceiptBillServiceImpl implements IOmsReceiptBillService, TodoCo
@Override @Override
public boolean multiInstanceApproveCallback(String activityName, ProcessInstance processInstance) { 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); return TodoCommonTemplate.super.multiInstanceApproveCallback(activityName, processInstance);
} }
} }

View File

@ -158,7 +158,7 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
if (customerInfo != null) { if (customerInfo != null) {
info.setCustomerAddress(customerInfo.getAddress()); 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) { if (info.getLastWorkUpdateTime() != null) {
LocalDate localDate = info.getLastWorkUpdateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); LocalDate localDate = info.getLastWorkUpdateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
Period between = Period.between(localDate, now); Period between = Period.between(localDate, now);
@ -604,7 +604,13 @@ public class ProjectInfoServiceImpl implements IProjectInfoService {
@Override @Override
public int editJoinTrial(ProjectInfo projectInfo) { 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) { private List<ProjectInfo> fetchProjectInfos(ProjectInfo projectInfo) {

View File

@ -294,6 +294,10 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
if (projectOrderInfo.getProjectId() == null) { if (projectOrderInfo.getProjectId() == null) {
throw new ServiceException("请选择项目"); 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())); List<ProjectOrderInfo> projectOrderInfos = this.selectProjectOrderInfoByProjectId(Collections.singletonList(projectOrderInfo.getProjectId()));
if (CollUtil.isNotEmpty(projectOrderInfos)) { if (CollUtil.isNotEmpty(projectOrderInfos)) {
throw new ServiceException("该项目存在订单流转,无法添加"); throw new ServiceException("该项目存在订单流转,无法添加");