Commit 5bf001ac authored by suhuiguang's avatar suhuiguang

1.使用登记、安装告知发起时增加设备过滤去掉流程中的设备

parent 5083ecf5
package com.yeejoin.amos.boot.module.jg.api.dto;
import lombok.Data;
/**
* @author Administrator
*/
@Data
public class CompanyEquipCountDto {
private String companyCode;
private String records;
}
package com.yeejoin.amos.boot.module.jg.api.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.jg.api.dto.CompanyEquipCountDto;
import com.yeejoin.amos.boot.module.jg.api.dto.JgInstallationNoticeDto;
import com.yeejoin.amos.boot.module.jg.api.entity.JgInstallationNotice;
import com.yeejoin.amos.boot.module.jg.api.vo.SortVo;
......@@ -38,4 +39,6 @@ public interface JgInstallationNoticeMapper extends CustomBaseMapper<JgInstallat
*/
@MapKey("sequenceNbr")
List<Map<String, Object>> queryEquipInformation(@Param("sequenceNbr") long sequenceNbr);
List<CompanyEquipCountDto> queryForFlowingEquipList();
}
......@@ -2,6 +2,7 @@ package com.yeejoin.amos.boot.module.jg.api.mapper;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.jg.api.dto.CompanyEquipCountDto;
import com.yeejoin.amos.boot.module.jg.api.dto.JgUseRegistrationDto;
import com.yeejoin.amos.boot.module.jg.api.entity.JgUseRegistration;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
......@@ -62,4 +63,6 @@ public interface JgUseRegistrationMapper extends BaseMapper<JgUseRegistration> {
@MapKey("id")
List<Map<String, Object>> selectEquipList(@Param("id")Long id);
List<CompanyEquipCountDto> queryForFlowingEquipList();
}
package com.yeejoin.amos.boot.module.jg.api.service;
import java.util.List;
import java.util.Set;
/**
* @author Administrator
*/
public interface IEquipUsedCheck {
/**
* 并发校验(页面同时提交或者页面同时打开多个时,某些设备都是为使用状态)校验设备流程在用状态及更新不在用为再使用状态
* @param record 设备唯一标识
* @param companyCode 登录人的公司代码
*/
void equipRepeatUsedCheck(String record, String companyCode);
/**
* 删除流程中的数据,释放redis空间(异常处理及驳回到发起节点、撤回到发起节点、完成时时进行)
* @param records 设备唯一标识
* @param companyCode 登录人的公司代码
*/
void delDataForCheckEquipRepeatUsed(List<String> records, String companyCode);
/**
* 获取在流程中的设备
* @param companyCode 公司编码
* @return 在用的设备集合
*/
Set<String> getEquipInFlow(String companyCode);
/**
* 可处理的业务类型
* @return String
*/
String applyBizType();
/**
* 数据初始化方法
*/
void init();
}
......@@ -183,4 +183,16 @@
isn.sequence_nbr = #{sequenceNbr}
LIMIT 1
</select>
<select id="queryForFlowingEquipList" resultType="com.yeejoin.amos.boot.module.jg.api.dto.CompanyEquipCountDto">
select
a.install_unit_credit_code as companyCode,
group_concat(b.equ_id) as records
from
tzs_jg_installation_notice a,
tzs_jg_installation_notice_eq b
where
a.sequence_nbr = b.equip_transfer_id
and (a.notice_status <![CDATA[ <> ]]> '6614' and a.notice_status <![CDATA[ <> ]]> '6615' and a.notice_status <![CDATA[ <> ]]>'6610' )
GROUP BY a.install_unit_credit_code
</select>
</mapper>
......@@ -541,4 +541,16 @@
</foreach>
ORDER BY ui.REC_DATE DESC
</select>
<select id="queryForFlowingEquipList"
resultType="com.yeejoin.amos.boot.module.jg.api.dto.CompanyEquipCountDto">
select
a.use_unit_credit_code as companyCode,
group_concat(b.equ_id) as records
from
tzs_jg_use_registration a,
tzs_jg_use_registration_eq b
where
a.sequence_nbr = b.equip_transfer_id
and (a.status <![CDATA[ <> ]]> '使用单位待提交' and a.status <![CDATA[ <> ]]> '一级受理已驳回' and a.status <![CDATA[ <> ]]> '使用单位已撤回')
</select>
</mapper>
......@@ -2,8 +2,6 @@ package com.yeejoin.amos.boot.module.jg.biz.controller;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.boot.module.jg.api.dto.JgInstallationAccDto;
import com.yeejoin.amos.boot.module.jg.api.dto.JgInstallationNoticeDto;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.JgInstallationNoticeServiceImpl;
import io.swagger.annotations.Api;
......@@ -79,12 +77,12 @@ public class JgInstallationByWorkFlowController {
@ApiOperation(httpMethod = "POST", value = "安装告知受理", notes = "安装告知受理")
public ResponseModel<JgInstallationNoticeDto> accept(@RequestBody Map<String, Object> model, String op) {
// TODO 受理安装告知流程
LinkedHashMap model1 = (LinkedHashMap)model.get("model");
String opinion = (String)model.get("opinion");
LinkedHashMap installationInfo = (LinkedHashMap)model1.get("installationInfo");
LinkedHashMap model1 = (LinkedHashMap) model.get("model");
String opinion = (String) model.get("opinion");
LinkedHashMap installationInfo = (LinkedHashMap) model1.get("installationInfo");
JgInstallationNoticeDto jgInstallationNoticeDto = JSON.parseObject(JSON.toJSONString(installationInfo), JgInstallationNoticeDto.class);
jgInstallationNoticeDto.setProcessAdvice(opinion);
jgInstallationNoticeServiceImpl.accept(jgInstallationNoticeDto,op);
jgInstallationNoticeServiceImpl.accept(jgInstallationNoticeDto, op);
return ResponseHelper.buildResponse(null);
}
}
......@@ -2,6 +2,7 @@ package com.yeejoin.amos.boot.module.jg.biz.init;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.module.jg.api.entity.*;
import com.yeejoin.amos.boot.module.jg.api.service.IEquipUsedCheck;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.*;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import org.springframework.boot.ApplicationArguments;
......@@ -45,6 +46,8 @@ public class ApplicationRunnerImpl implements ApplicationRunner {
private ReportAnalysisServiceImpl reportAnalysisService;
private List<IEquipUsedCheck> equipUsedCheckList;
public ApplicationRunnerImpl(JgUseRegistrationServiceImpl useRegistrationService,
CommonServiceImpl commonService,
JgInstallationNoticeServiceImpl installationNoticeService,
......@@ -59,7 +62,8 @@ public class ApplicationRunnerImpl implements ApplicationRunner {
JgMaintenanceContractServiceImpl maintenanceContractService,
JgScrapCancelServiceImpl scrapCancelService,
JgChangeRegistrationNameServiceImpl changeRegistrationNameService,
ReportAnalysisServiceImpl reportAnalysisService) {
ReportAnalysisServiceImpl reportAnalysisService,
List<IEquipUsedCheck> equipUsedCheckList) {
this.commonService = commonService;
this.useRegistrationService = useRegistrationService;
......@@ -89,6 +93,8 @@ public class ApplicationRunnerImpl implements ApplicationRunner {
this.changeRegistrationNameService =changeRegistrationNameService;
this.reportAnalysisService = reportAnalysisService;
this.equipUsedCheckList = equipUsedCheckList;
}
......@@ -175,5 +181,8 @@ public class ApplicationRunnerImpl implements ApplicationRunner {
// 统计接收机构树 根节点缓存预热
reportAnalysisService.initRootOrgReceiveTree2Redis();
// 流程中的设备统计数据预热
equipUsedCheckList.forEach(IEquipUsedCheck::init);
}
}
package com.yeejoin.amos.boot.module.jg.biz.service.impl;
import com.yeejoin.amos.boot.module.jg.api.service.IEquipUsedCheck;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* @author Administrator
*/
@Component
public class EquipUsedCheckStrategyContext implements ApplicationContextAware {
private static Map<String, IEquipUsedCheck> iActionExecuteStrategyHashMap = new HashMap<>();
public static IEquipUsedCheck getUsedStrategy(String bizType) {
return Optional.ofNullable(iActionExecuteStrategyHashMap.get(bizType)).orElseThrow(() -> new RuntimeException(String.format("not found %s type strategy", bizType)));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, IEquipUsedCheck> strategyBeans = applicationContext.getBeansOfType(IEquipUsedCheck.class);
if (strategyBeans.isEmpty()) {
return;
}
for (IEquipUsedCheck strategy : strategyBeans.values()) {
iActionExecuteStrategyHashMap.put(strategy.applyBizType(), strategy);
}
}
}
......@@ -1218,6 +1218,7 @@ public class IdxBizJgRegisterInfoServiceImpl extends BaseService<IdxBizJgRegiste
BoolQueryBuilder nullOrEmptyQuery = QueryBuilders.boolQuery()
.mustNot(QueryBuilders.wildcardQuery("USE_UNIT_CREDIT_CODE", "*"));
boolMust.must(nullOrEmptyQuery);
this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "installNotice");
} else if (ValidationUtil.equals(queryType, "WB")) {
// 查询 维保备案【可绑定设备列表】【(EQU_STATE=== null || "")】
BoolQueryBuilder wbBuilder = QueryBuilders.boolQuery();
......@@ -1229,6 +1230,7 @@ public class IdxBizJgRegisterInfoServiceImpl extends BaseService<IdxBizJgRegiste
syBuilder.mustNot(QueryBuilders.existsQuery("EQU_STATE"));
syBuilder.mustNot(QueryBuilders.wildcardQuery("USE_ORG_CODE", "*"));
boolMust.must(syBuilder);
this.setRepeatUsedCheckFilterParam(boolMust, companyCode, "useRegister");
}
}
......@@ -1435,6 +1437,18 @@ public class IdxBizJgRegisterInfoServiceImpl extends BaseService<IdxBizJgRegiste
}
/**
* 设置安装告知使用的设备不能包括正在进行中的流程
* @param boolMust
* @param companyCode
*/
private void setRepeatUsedCheckFilterParam(BoolQueryBuilder boolMust, String companyCode, String bizType) {
Set<String> records = EquipUsedCheckStrategyContext.getUsedStrategy(bizType).getEquipInFlow(companyCode);
if(records.size() >0){
boolMust.mustNot(QueryBuilders.termsQuery("SEQUENCE_NBR.keyword", records));
}
}
/**
* 获取当前登录人单位类型
*
* @return
......
package com.yeejoin.amos.boot.module.jg.biz.service.impl;
import com.yeejoin.amos.boot.module.jg.api.dto.CompanyEquipCountDto;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgInstallationNoticeMapper;
import com.yeejoin.amos.boot.module.jg.api.service.IEquipUsedCheck;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @author Administrator
*/
@Component
@Slf4j
public class InstallNoticeEquipUsedCheckImpl implements IEquipUsedCheck {
private RedissonClient redissonClient;
private String bizType = "installNotice";
private JgInstallationNoticeMapper installationNoticeMapper;
public InstallNoticeEquipUsedCheckImpl(RedissonClient redissonClient, JgInstallationNoticeMapper installationNoticeMapper) {
this.redissonClient = redissonClient;
this.installationNoticeMapper = installationNoticeMapper;
}
/**
* 并发校验(页面同时提交或者页面同时打开多个时,某些设备都是为使用状态)校验设备流程在用状态及更新不在用为再使用状态
*
* @param record 设备唯一标识
* @param companyCode 登录人的公司代码
*/
@Override
public void equipRepeatUsedCheck(String record, String companyCode) {
RLock lock = redissonClient.getLock(this.getRepeatUsedCheckLockKey(companyCode, bizType, record));
try {
boolean isLocked = lock.tryLock(0, 180, TimeUnit.SECONDS);
if (!isLocked) {
log.error("设备:{}在被其他业务使用,加锁失败", record);
throw new BadRequest("存在其他业务在使用设备,请刷新后重试!");
}
RBucket<Set<String>> RBucket = redissonClient.getBucket(this.getFlowingEquipRedisKey(companyCode, bizType));
Set<String> equipListOfUsed = RBucket.get();
if (equipListOfUsed != null && equipListOfUsed.contains(record)) {
throw new BadRequest("存在设备正在同时被其他流程使用,请刷新后重试!");
}
if (equipListOfUsed == null || equipListOfUsed.isEmpty()) {
equipListOfUsed = new TreeSet<>();
}
equipListOfUsed.add(record);
redissonClient.getBucket(this.getFlowingEquipRedisKey(companyCode, bizType)).set(equipListOfUsed);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
private String getRepeatUsedCheckLockKey(String companyCode, String bizType, String record) {
return String.format("%s-%s-%s-%s", "JG_REPEAT_CHECK", companyCode, bizType, record);
}
private String getFlowingEquipRedisKey(String companyCode, String type) {
return String.format("%s:%s:%s", "EQUIP_IN_FLOWING", companyCode, type);
}
/**
* 删除流程中的数据,释放redis空间(异常处理及驳回到发起节点、撤回到发起节点、完成时时进行)
*
* @param records 设备唯一标识
* @param companyCode 登录人的公司代码
*/
@Override
public void delDataForCheckEquipRepeatUsed(List<String> records, String companyCode) {
RBucket<Set<String>> rBucket = redissonClient.getBucket(this.getFlowingEquipRedisKey(companyCode, bizType));
Set<String> equipListOfUsed = rBucket.get();
equipListOfUsed = equipListOfUsed.stream().filter(record -> !records.contains(record)).collect(Collectors.toSet());
rBucket.set(equipListOfUsed);
}
@Override
public Set<String> getEquipInFlow(String companyCode) {
RBucket<Set<String>> rBucket = redissonClient.getBucket(this.getFlowingEquipRedisKey(companyCode, bizType));
return rBucket.get();
}
@Override
public String applyBizType() {
return bizType;
}
@Override
public void init() {
List<CompanyEquipCountDto> companyEquipCountDtos = installationNoticeMapper.queryForFlowingEquipList();
companyEquipCountDtos.forEach(c -> {
RBucket<Set<String>> rBucket = redissonClient.getBucket(this.getFlowingEquipRedisKey(c.getCompanyCode(), bizType));
rBucket.set(Arrays.stream(c.getRecords().split(",")).collect(Collectors.toSet()));
});
}
}
......@@ -243,6 +243,7 @@ public class JgInstallationNoticeServiceImpl extends BaseService<JgInstallationN
*
* @param noticeDto 安装告知
*/
@Override
@SuppressWarnings({"rawtypes", "Duplicates"})
@Transactional
public JgInstallationNoticeDto updateInstallationNotice(String submitType, JgInstallationNoticeDto noticeDto, String op) {
......@@ -252,7 +253,7 @@ public class JgInstallationNoticeServiceImpl extends BaseService<JgInstallationN
// 字段转换
this.convertField(noticeDto);
JgInstallationNotice notice = this.getById(noticeDto.getSequenceNbr());
this.checkRepeatUsed(submitType, notice);
if (SUBMIT_TYPE_FLOW.equals(submitType)) {
if (!StringUtils.hasText(noticeDto.getInstanceId())) {
// 发起流程
......@@ -356,6 +357,15 @@ public class JgInstallationNoticeServiceImpl extends BaseService<JgInstallationN
return noticeDto;
}
private void checkRepeatUsed(String submitType, JgInstallationNotice jgInstallationNotice) {
if (SUBMIT_TYPE_FLOW.equals(submitType)) {
LambdaQueryWrapper<JgInstallationNoticeEq> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(JgInstallationNoticeEq::getEquipTransferId, jgInstallationNotice.getSequenceNbr());
JgInstallationNoticeEq jgRelationEquip = jgInstallationNoticeEqMapper.selectOne(queryWrapper);
EquipUsedCheckStrategyContext.getUsedStrategy("installNotice").equipRepeatUsedCheck(jgRelationEquip.getEquId(), jgInstallationNotice.getInstallUnitCreditCode());
}
}
/**
* 分页查询
......@@ -509,6 +519,10 @@ public class JgInstallationNoticeServiceImpl extends BaseService<JgInstallationN
if (CollectionUtils.isEmpty(deviceList)) {
throw new BadRequest("设备列表为空");
}
// 提交时对设备状态进行校验(处理并发问题,一个未被使用的设备同时被多个使用这打开,同时提交发起申请) todo 回滚异常未写
if (SUBMIT_TYPE_FLOW.equals(submitType)) {
this.repeatUsedEquipCheck(deviceList, reginParams.getCompany().getCompanyCode());
}
// 获取告知单号
ResponseModel<List<String>> listResponseModel = tzsServiceFeignClient.applicationFormCode(ApplicationFormTypeEnum.AZGZ.getCode(), deviceList.size());
if (!ObjectUtils.isEmpty(listResponseModel) && listResponseModel.getStatus() != HttpStatus.OK.value()) {
......@@ -547,6 +561,10 @@ public class JgInstallationNoticeServiceImpl extends BaseService<JgInstallationN
return list;
}
private void repeatUsedEquipCheck(List<Map<String, Object>> equipList, String companyCode) {
equipList.forEach(equipMap -> EquipUsedCheckStrategyContext.getUsedStrategy("installNotice").equipRepeatUsedCheck(String.valueOf(equipMap.get("SEQUENCE_NBR")), companyCode));
}
private void updateRedisBatch(List<JgInstallationNotice> jgInstallationNotices) {
jgInstallationNotices.stream().filter(n -> StringUtil.isNotEmpty(n.getInstanceId())).forEach(jgInstallationNotice -> {
commonService.saveExecuteFlowData2Redis(jgInstallationNotice.getInstanceId(), this.buildInstanceRuntimeData(jgInstallationNotice));
......@@ -826,6 +844,7 @@ public class JgInstallationNoticeServiceImpl extends BaseService<JgInstallationN
jsonObject.put("nextTaskId", jgInstallationNotice.getNextTaskId());
commonService.rollbackTask(jgInstallationNotice.getInstanceId(), jsonObject);
commonService.saveExecuteFlowData2Redis(instanceId, this.buildInstanceRuntimeData(jgInstallationNotice));
this.delRepeatUseEquipData(jgInstallationNotice);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
......@@ -835,6 +854,18 @@ public class JgInstallationNoticeServiceImpl extends BaseService<JgInstallationN
}
}
/**
* 删除 redis校验重复引用设备的数据
*
* @param jgInstallationNotice 安装告知entry
*/
private void delRepeatUseEquipData(JgInstallationNotice jgInstallationNotice) {
LambdaQueryWrapper<JgInstallationNoticeEq> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(JgInstallationNoticeEq::getEquipTransferId, jgInstallationNotice.getSequenceNbr());
JgInstallationNoticeEq jgRelationEquip = jgInstallationNoticeEqMapper.selectOne(queryWrapper);
EquipUsedCheckStrategyContext.getUsedStrategy("installNotice").delDataForCheckEquipRepeatUsed(Collections.singletonList(jgRelationEquip.getEquId()), jgInstallationNotice.getInstallUnitCreditCode());
}
@Transactional(rollbackFor = Exception.class)
public void accept(JgInstallationNoticeDto dto, String op) {
String instanceId = dto.getInstanceId();
......@@ -957,6 +988,7 @@ public class JgInstallationNoticeServiceImpl extends BaseService<JgInstallationN
BeanUtils.copyProperties(jgInstallationNotice, taskMessageDto);
taskMap.put("model", taskMessageDto);
taskV2Model = commonService.updateTaskModel(taskMap);
this.delRepeatUseEquipData(jgInstallationNotice);
} else {
jgInstallationNotice.setNextExecuteIds(workflowResultDto.getNextExecutorRoleIds());
jgInstallationNotice.setNextExecuteUserIds(workflowResultDto.getNextExecutorUserIds());
......@@ -1014,6 +1046,7 @@ public class JgInstallationNoticeServiceImpl extends BaseService<JgInstallationN
taskModelDto.setExecuteUserIds(workflowResultDto.getNextExecutorUserIds());
taskModelDto.setModel(taskMessageDto);
commonService.buildTaskModel(Collections.singletonList(taskModelDto));
this.delRepeatUseEquipData(jgInstallationNotice);
}
jgInstallationNotice.setNextExecuteUserIds(workflowResultDto.getNextExecutorUserIds());
jgInstallationNotice.setNextExecuteIds(workflowResultDto.getNextExecutorRoleIds());
......
......@@ -142,6 +142,8 @@ public class JgUseRegistrationServiceImpl extends BaseService<JgUseRegistrationD
@Autowired
private JgUseRegistrationMapper jgUseRegistrationMapper;
private final List<String> NOT_FLOWING_STATE = Arrays.asList("使用单位待提交","一级受理已驳回", "使用单位已撤回", "已完成");
/**
* @param auditPassDate 通过时间
* @param exportParamsMap 参数map
......@@ -337,6 +339,8 @@ public class JgUseRegistrationServiceImpl extends BaseService<JgUseRegistrationD
*/
private List<Map<String, Object>> handleUseRegistration(JSONObject map) {
ReginParams reginParams = JSONObject.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
// 提交时进行校验设备是否在流程中使用(并发及同时打开多个相同的页面时才会出现此种情况)
checkForRepeatUsedEquip(map, reginParams);
// 使用登记信息
JgUseRegistration jgUseRegistration = new JgUseRegistration();
jgUseRegistration.setRegDate(new Date());
......@@ -495,6 +499,12 @@ public class JgUseRegistrationServiceImpl extends BaseService<JgUseRegistrationD
return this.baseMapper.getDetailById(jgUseRegistration.getSequenceNbr());
}
private void checkForRepeatUsedEquip(JSONObject map, ReginParams reginParams) {
if (!ObjectUtils.isEmpty(map.get("submit"))) {
EquipUsedCheckStrategyContext.getUsedStrategy("useRegister").equipRepeatUsedCheck(map.get("equipId").toString(), reginParams.getCompany().getCompanyCode());
}
}
/**
* 按单位办理
*
......@@ -1054,6 +1064,7 @@ public class JgUseRegistrationServiceImpl extends BaseService<JgUseRegistrationD
this.updateData(jgUseRegistration.getSequenceNbr(), operate, workflowResultDto, false, carNumber);
}
}
this.clearDataForCheckEquipRepeatUsed(jgUseRegistration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
......@@ -1121,6 +1132,7 @@ public class JgUseRegistrationServiceImpl extends BaseService<JgUseRegistrationD
commonServiceImpl.rollbackTask(instanceId, jsonObject);
// redis流程实时数据更新
commonServiceImpl.saveExecuteFlowData2Redis(instanceId, this.buildInstanceRuntimeData(data));
this.clearDataForCheckEquipRepeatUsed(data);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
......@@ -1130,6 +1142,20 @@ public class JgUseRegistrationServiceImpl extends BaseService<JgUseRegistrationD
}
}
private void clearDataForCheckEquipRepeatUsed(JgUseRegistration useRegistration){
// 新查询原因 useRegistration 数据状态是旧的
JgUseRegistration useRegistrationDb = this.getById(useRegistration.getSequenceNbr());
LambdaQueryWrapper<JgUseRegistrationEq> lambda = new QueryWrapper<JgUseRegistrationEq>().lambda();
lambda.eq(JgUseRegistrationEq::getEquipTransferId, useRegistration.getSequenceNbr());
lambda.select(JgUseRegistrationEq::getEquId);
List<JgUseRegistrationEq> eqList = jgRelationEquipMapper.selectList(lambda);
// 在使用单位待提交、一级受理已驳回、使用单位已撤回后清除关联的设备,保证可以再次新提单子选择相同的设备进行提交及原有单子的提交校验数据准备
if(NOT_FLOWING_STATE.contains(useRegistrationDb.getStatus())){
List<String> records = eqList.stream().map(JgUseRegistrationEq::getEquId).collect(Collectors.toList());
EquipUsedCheckStrategyContext.getUsedStrategy("useRegister").delDataForCheckEquipRepeatUsed(records,useRegistration.getUseUnitCreditCode());
}
}
public void deleteBatch(List<Long> ids) {
JgUseRegistration jgUseRegistration = new JgUseRegistration();
jgUseRegistration.setIsDelete(true);
......
package com.yeejoin.amos.boot.module.jg.biz.service.impl;
import com.yeejoin.amos.boot.module.jg.api.dto.CompanyEquipCountDto;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgUseRegistrationMapper;
import com.yeejoin.amos.boot.module.jg.api.service.IEquipUsedCheck;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @author Administrator
*/
@Component
@Slf4j
public class UseRegisterEquipUsedCheckImpl implements IEquipUsedCheck {
private RedissonClient redissonClient;
private String bizType = "useRegister";
private JgUseRegistrationMapper useRegistrationMapper;
public UseRegisterEquipUsedCheckImpl(RedissonClient redissonClient, JgUseRegistrationMapper useRegistrationMapper) {
this.redissonClient = redissonClient;
this.useRegistrationMapper = useRegistrationMapper;
}
/**
* 并发校验(页面同时提交或者页面同时打开多个时,某些设备都是为使用状态)校验设备流程在用状态及更新不在用为再使用状态
*
* @param record 设备唯一标识
* @param companyCode 登录人的公司代码
*/
@Override
public void equipRepeatUsedCheck(String record, String companyCode) {
RLock lock = redissonClient.getLock(this.getRepeatUsedCheckLockKey(companyCode, bizType, record));
try {
boolean isLocked = lock.tryLock(0, 180, TimeUnit.SECONDS);
if (!isLocked) {
log.error("设备:{}在被其他业务使用,加锁失败", record);
throw new BadRequest("存在其他业务在使用设备,请刷新后重试!");
}
RBucket<Set<String>> RBucket = redissonClient.getBucket(this.getFlowingEquipRedisKey(companyCode, bizType));
Set<String> equipListOfUsed = RBucket.get();
if (equipListOfUsed != null && equipListOfUsed.contains(record)) {
throw new BadRequest("存在设备正在同时被其他流程使用,请刷新后重试!");
}
if (equipListOfUsed == null || equipListOfUsed.isEmpty()) {
equipListOfUsed = new TreeSet<>();
}
equipListOfUsed.add(record);
redissonClient.getBucket(this.getFlowingEquipRedisKey(companyCode, bizType)).set(equipListOfUsed);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
private String getRepeatUsedCheckLockKey(String companyCode, String bizType, String record) {
return String.format("%s-%s-%s-%s", "JG_REPEAT_CHECK", companyCode, bizType, record);
}
private String getFlowingEquipRedisKey(String companyCode, String type) {
return String.format("%s:%s:%s", "EQUIP_IN_FLOWING", companyCode, type);
}
/**
* 删除流程中的数据,释放redis空间(异常处理及驳回到发起节点、撤回到发起节点、完成时时进行)
*
* @param records 设备唯一标识
* @param companyCode 登录人的公司代码
*/
@Override
public void delDataForCheckEquipRepeatUsed(List<String> records, String companyCode) {
RBucket<Set<String>> rBucket = redissonClient.getBucket(this.getFlowingEquipRedisKey(companyCode, bizType));
Set<String> equipListOfUsed = rBucket.get();
equipListOfUsed = equipListOfUsed.stream().filter(record -> !records.contains(record)).collect(Collectors.toSet());
rBucket.set(equipListOfUsed);
}
@Override
public Set<String> getEquipInFlow(String companyCode) {
RBucket<Set<String>> rBucket = redissonClient.getBucket(this.getFlowingEquipRedisKey(companyCode, bizType));
return rBucket.get();
}
@Override
public String applyBizType() {
return bizType;
}
@Override
public void init() {
List<CompanyEquipCountDto> companyEquipCountDtos = useRegistrationMapper.queryForFlowingEquipList();
companyEquipCountDtos.forEach(c -> {
RBucket<Set<String>> rBucket = redissonClient.getBucket(this.getFlowingEquipRedisKey(c.getCompanyCode(), bizType));
rBucket.set(Arrays.stream(c.getRecords().split(",")).collect(Collectors.toSet()));
});
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment