package com.hotent.baseInfo.manager.impl; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.hotent.base.query.PageList; import com.hotent.base.util.StringUtil; import com.hotent.baseInfo.model.CostCatalog; import com.hotent.baseInfo.model.CostDocumentWh; import com.hotent.baseInfo.dao.CostDocumentWhDao; import com.hotent.baseInfo.manager.CostDocumentWhManager; import com.hotent.base.manager.impl.BaseManagerImpl; import com.hotent.baseInfo.req.CostDocumentWhPageReq; import com.hotent.baseInfo.resp.AuditedUnitDetailResp; import com.hotent.baseInfo.resp.CostDocumentWhDetailResp; import com.hotent.constant.BaseConstant; import com.hotent.req.IdReq; import com.hotent.uc.api.model.IUser; import com.hotent.uc.exception.BaseException; import com.hotent.uc.manager.UserManager; import com.hotent.uc.model.User; import com.hotent.uc.util.ContextUtil; import com.hotent.util.AreaCodeUtil; import com.hotent.util.CopyUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import java.io.Serializable; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Resource; import com.hotent.base.util.BeanUtils; /** * 文书文号管理表 服务实现类 * * @author 超级管理员 * @company 山西清众科技股份有限公司 * @since 2025-09-14 */ @Service public class CostDocumentWhManagerImpl extends BaseManagerImpl implements CostDocumentWhManager { @Autowired private UserManager userService; @Override public CostDocumentWhDetailResp getDetail(String id) { CostDocumentWh costDocumentWh = this.get(id); CostDocumentWhDetailResp detailResp = CopyUtil.copy(costDocumentWh, CostDocumentWhDetailResp.class); //单位级别:0:省/自治区/直辖市 1:市级 2:县级 if (ObjectUtil.isNotEmpty(costDocumentWh.getAreaCode()) && ObjectUtil.isNotEmpty(costDocumentWh.getAreaLevel())) { //如果是区县级 if (BaseConstant.REGION_LEVEL_COUNTY.equals(costDocumentWh.getAreaLevel())) { String cityCode = AreaCodeUtil.getCityCode(costDocumentWh.getAreaCode()); String provinceCode = AreaCodeUtil.getProvinceCode(cityCode); detailResp.setCity(cityCode); detailResp.setProvince(provinceCode); detailResp.setCounty(costDocumentWh.getAreaCode()); } else if (BaseConstant.REGION_LEVEL_CITY.equals(costDocumentWh.getAreaLevel())) { String provinceCode = AreaCodeUtil.getProvinceCode(costDocumentWh.getAreaCode()); detailResp.setProvince(provinceCode); detailResp.setCity(costDocumentWh.getAreaCode()); } else if (BaseConstant.REGION_LEVEL_PROVINCE.equals(costDocumentWh.getAreaLevel())) { detailResp.setProvince(costDocumentWh.getAreaCode()); } else { detailResp.setProvince("未知编码"); } } return detailResp; } @Override @Transactional public void createOrUpdate(CostDocumentWh costDocumentWh) throws Exception { //TODO 生成规则 使用表达式 /** * 分省、市、县三级分别对本单位的成本监审过程中相关文书的文号前缀统一管理, * 例如:晋成审报〔2025〕2号 * 涉及的文号前缀类型包括如下: *  《政府定价成本监审结论报告》文号:**成审报〔****〕**号 *  《成本监审通知书》文号:**成审〔****〕**号 *  《成本审核初步意见告知书》文号:**成审告〔****〕**号 *  《成本监审补充资料通知书》文号:**成审补〔****〕**号 *  《中止定价成本监审通知书》文号:**成审中〔****〕**号 * {prefixText}成审报 {year} {currentValue}号 */ if (!isValidRulePattern(costDocumentWh.getRulePattern())) { throw new BaseException("规则表达式错误 按要求填写:{prefixText}成审 {year} {currentValue}号"); } IUser iUser = ContextUtil.getCurrentUser(); User user = userService.getByAccount(iUser.getAccount()); if (StringUtil.isNotEmpty(costDocumentWh.getId())) { costDocumentWh.setUpdateBy(user.getAccount()); costDocumentWh.setUpdateTime(LocalDateTime.now()); }else { costDocumentWh.setCreateTime(LocalDateTime.now()); costDocumentWh.setCreateBy(user.getAccount()); } //新建或更新 this.saveOrUpdate(costDocumentWh); } private boolean isValidRulePattern(String rulePattern) { if (rulePattern == null || rulePattern.isEmpty()) { return false; } // 检查必需的占位符是否存在 if (!rulePattern.contains("{prefixText}") || !rulePattern.contains("{year}") || !rulePattern.contains("{currentValue}")) { return false; } // 检查占位符格式是否正确(不包含嵌套或未闭合情况) String placeholderRegex = "\\{[^\\{\\}]*\\}"; Pattern placeholderPattern = Pattern.compile(placeholderRegex); Matcher matcher = placeholderPattern.matcher(rulePattern); // 提取所有占位符 List placeholders = new ArrayList<>(); while (matcher.find()) { placeholders.add(matcher.group()); } // 验证必需占位符都在其中 if (!placeholders.contains("{prefixText}") || !placeholders.contains("{year}") || !placeholders.contains("{currentValue}")) { return false; } // 验证没有非法字符(可根据实际需求调整) String allowedPattern = "^[\\w\\u4e00-\\u9fa5\\{\\}\\[\\]\\(\\)〔〕号\\s]+$"; return rulePattern.matches(allowedPattern); } @Override public CostDocumentWh updateCurrentValue(String id) { CostDocumentWh costDocumentWh = this.get(id); if (costDocumentWh == null) { throw new BaseException("数据不存在"); } if (!BaseConstant.GENERATE_TYPE_INCREMENTAL.equals(costDocumentWh.getGenerateType())) { throw new BaseException("类型不存在"); } costDocumentWh.setCurrentValue(costDocumentWh.getCurrentValue() + 1); costDocumentWh.setLastGenerateDate(LocalDate.now()); this.update(costDocumentWh, new LambdaUpdateWrapper().eq(CostDocumentWh::getId, id)); //返回文号 String replace = costDocumentWh.getRulePattern().replace("{prefixText}", costDocumentWh.getPrefixText()) .replace("{year}", costDocumentWh.getYear()).replace("{currentValue}", costDocumentWh.getCurrentValue().toString()); costDocumentWh.setRulePattern(replace); return costDocumentWh; } @Override public void deleteByIds(List ids) { List costDocumentWhs = this.listByIds(ids); if (costDocumentWhs!= null){ costDocumentWhs.forEach(item -> { item.setIsDeleted(BaseConstant.DELETE_FLAG); }); this.updateBatchById(costDocumentWhs); } } @Override public PageList getDocumentWhList(CostDocumentWhPageReq req) throws Exception { // 构建查询条件 /*LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(CostDocumentWh::getIsDeleted, BaseConstant.NORMAL_STATUS); // 根据查询条件过滤 if (StringUtil.isNotEmpty(req.getWhType())) { queryWrapper.eq(CostDocumentWh::getWhType, req.getWhType()); } if (StringUtil.isNotEmpty(req.getWhName())) { queryWrapper.like(CostDocumentWh::getWhName, req.getWhName()); }*/ // 创建分页对象 Page page = new Page<>(req.getPage(), req.getPageSize()); //Page respPage = this.page(page, queryWrapper); IUser iUser = ContextUtil.getCurrentUser(); User user = userService.getByAccount(iUser.getAccount()); req.setDataScope(user.getDataScope()); req.setProvinceCode(user.getProvinceCode()); req.setCityCode(user.getCityCode()); req.setCountyCode(user.getCountyCode()); Page respPage= baseMapper.getPageList(page,req.getDataScope() ,req.getProvinceCode(),req.getCityCode() ,req.getCountyCode() ,req.getWhType() ,req.getWhName()); List records = respPage.getRecords(); for (CostDocumentWh costDocumentWh : records) { //返回文号 String replace = costDocumentWh.getRulePattern().replace("{prefixText}", costDocumentWh.getPrefixText()) .replace("{year}", costDocumentWh.getYear()).replace("{currentValue}", costDocumentWh.getCurrentValue().toString()); costDocumentWh.setWhNo(replace); } return new PageList<>(respPage); } public void remove(Serializable id) { CostDocumentWh costDocumentWh = this.get(id); if (costDocumentWh == null || BaseConstant.DELETE_FLAG.equals(costDocumentWh.getIsDeleted())) { throw new BaseException("数据不存在"); } costDocumentWh.setIsDeleted(BaseConstant.DELETE_FLAG); this.update(costDocumentWh); } }