// 获取近30天 员工持股业绩考核内容为空的数据
List<OssMetaGqDto> ossMetaList = iOssMetaDataService.selectOssEmployeeStockPathList();
if (CollectionUtils.isEmpty(ossMetaList)) {
log.info("未加载到待解析的员工持股草案。");
return;
}
List<EmployeeStockInfo> employeeStockInfoList = Lists.newArrayList();
List<EmployeeStockUserInfo> employeeStockUserInfoList = Lists.newArrayList();
List<EmployeeStockUnlockSchedule> employeeStockUnlockScheduleList = Lists.newArrayList();
for (OssMetaGqDto ossMetaGqDto : ossMetaList) {
if (ossMetaGqDto == null || StringUtils.isEmpty(ossMetaGqDto.getFilePath())) {
continue;
}
// 读取员工持股草案PDF文件内容
PdfFileDto pdfFileDto = iAliYunOssDataService.fetchPdfFileDto(ossMetaGqDto.getFilePath());
if (pdfFileDto == null || CollectionUtils.isEmpty(pdfFileDto.getCatalogMap())
|| CollectionUtils.isEmpty(pdfFileDto.getChapterContentMap())) {
continue;
}
// 公司业绩考核内容
String companyAppraisal = employeeStockAppraisalService.fetchCompanyAppraisal(pdfFileDto);
// 个人业绩考核内容
String personAppraisal = employeeStockAppraisalService.fetchPersonAppraisal(pdfFileDto);
// 摊销成本
BigDecimal amortizedCost = employeeStockAmortizedService.fetchAmortizedCost(pdfFileDto);
// 解析激励对象
List<EmployeeStockUserInfo> stockUserInfoList = employeeStockUserService.fetchStockUserList(ossMetaGqDto.getPlanId(), pdfFileDto);
if (!CollectionUtils.isEmpty(stockUserInfoList)) {
employeeStockUserInfoList.addAll(stockUserInfoList);
}
// 行权解锁
List<EmployeeStockUnlockSchedule> unlockList = employeeStockUnlockService.fetchUnlockList(ossMetaGqDto.getPlanId(), pdfFileDto);
if(StringUtils.isNotEmpty(companyAppraisal) || StringUtils.isNotEmpty(personAppraisal) || amortizedCost.intValue() > 0) {
EmployeeStockInfo employeeStockInfo = EmployeeStockInfo.builder()
.id(ossMetaGqDto.getPlanId())
.companyAppraisalContent(companyAppraisal)
.personalAppraisalContent(personAppraisal)
.amortizedCost(amortizedCost)
.build();
employeeStockInfoList.add(employeeStockInfo);
}
if (!CollectionUtils.isEmpty(unlockList)) {
employeeStockUnlockScheduleList.addAll(unlockList);
}
}
package com.realize.project.oss.service.impl;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.Protocol;
import com.aliyun.oss.model.OSSObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.realize.framework.config.AliyunOSSConfig;
import com.realize.project.oss.dto.PdfFileDto;
import com.realize.project.oss.scene.CatalogNumber;
import com.realize.project.oss.scene.CatalogUtils;
import com.realize.project.oss.scene.CatalogWord;
import com.realize.project.oss.service.IAliYunOssDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
/**
* aliyun oss
*
* @author zhangtao
* @date 2022-07-27
*/
@Slf4j
@Service
public class AliYunOssDataServiceImpl implements IAliYunOssDataService {
@Autowired
private AliyunOSSConfig aliyunOSSConfig;
@Override
public PdfFileDto fetchPdfFileDto(String filePath) {
String prefix = "sync_files/";
List<String> contentList = fetchContentByFilePath((prefix).concat(filePath));
// 解析目录和章节内容 默认目录格式:第一章....1
boolean dataStatus = false;
Map<Integer, List<String>> chapterContentMap = Maps.newHashMap();
Map<Integer, String> catalogMap = CatalogWord.fetchCatalogMap(contentList);
if (!CollectionUtils.isEmpty(catalogMap)) {
chapterContentMap = CatalogWord.fetchChapterContentMap(contentList);
dataStatus = true;
}
// 目录格式:一、 释义 ................7
if (!dataStatus && CollectionUtils.isEmpty(catalogMap)) {
catalogMap = CatalogNumber.fetchCatalogMap(contentList);
if (!CollectionUtils.isEmpty(catalogMap)) {
chapterContentMap = CatalogNumber.fetchChapterContentMap(contentList);
}
}
// 当目录为空时,直接从正文解析目录 第一章....1
if (CollectionUtils.isEmpty(chapterContentMap)) {
chapterContentMap = CatalogWord.fetchChapterContentMap(contentList);
}
// 当目录为空时,直接从正文解析目录 一、 释义 ................7
if (CollectionUtils.isEmpty(chapterContentMap)) {
chapterContentMap = CatalogNumber.fetchChapterContentMap(contentList);
}
// 目录与章节内容不一致
if (catalogMap.size() != chapterContentMap.size()) {
Map<Integer, List<String>> newChapterContentMap = CatalogUtils.distinctMap(chapterContentMap);
catalogMap = CatalogUtils.refactorCatalogMap(newChapterContentMap);
}
// 构建pdfFileDto对象
PdfFileDto pdfFileDto = PdfFileDto.builder()
.catalogMap(catalogMap)
.chapterContentMap(chapterContentMap)
.build();
return pdfFileDto;
}
/**
* 获取oss文件内容
* @param filePath
* @return
*/
@Override
public List<String> fetchContentByFilePath(String filePath) {
List<String> fileContentList = Lists.newArrayList();
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setProtocol(Protocol.HTTPS);
// 创建Oss Client实例
OSS ossClient = new OSSClientBuilder().build(
aliyunOSSConfig.getOssEndpointUrl(),
aliyunOSSConfig.getAccessKeyId(),
aliyunOSSConfig.getAccessKeySecret()
);
try {
OSSObject ossObject = ossClient.getObject(aliyunOSSConfig.getOssBucketName(), filePath);
// 调用ossObject.getObjectContent获取文件输入流,可读取此输入流获取其内容。
InputStream content = ossObject.getObjectContent();
if (content != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
while (true) {
String line = reader.readLine();
if (line == null) break;
fileContentList.add(line);
}
// 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
content.close();
}
} catch (Exception e) {
log.error("oss reader error: "+ e.getMessage());
}
// 关闭OSSClient。
ossClient.shutdown();
return fileContentList;
}
}
package com.realize.project.data.service.impl;
import com.google.common.collect.Lists;
import com.realize.project.data.service.EmployeeStockAmortizedService;
import com.realize.project.oss.dto.PdfFileDto;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 员工持股摊销成本
*/
@Service
public class EmployeeStockAmortizedServiceImpl extends AbstractFileParser implements EmployeeStockAmortizedService {
@Override
public BigDecimal fetchAmortizedCost(PdfFileDto pdfFileDto) {
BigDecimal amortizedCost = new BigDecimal(0);
// 获取章节内容
List<String> chapterContents = fetchChapterContents(pdfFileDto);
if (CollectionUtils.isEmpty(chapterContents)) {
return amortizedCost;
}
// 解析摊销成本
amortizedCost = parserAmortizedCost(chapterContents);
return amortizedCost;
}
/**
* 获取章节内容
* @param pdfFileDto
* @return
*/
private List<String> fetchChapterContents(PdfFileDto pdfFileDto) {
String excludeRegex = "";
List<String> chapterContents = Lists.newArrayList();
// 获取业绩考核所在章节内容, 逐渐放低匹配精确度
// 场景 第九章 本员工持股计划的会计处理
String regex = ".*(员工持股计划|持股计划).*会计处理.*";
chapterContents = fetchChapterContents(pdfFileDto, regex, excludeRegex);
return chapterContents;
}
/**
* 解析摊销成本
* @param excerptList
* @return
*/
private BigDecimal parserAmortizedCost(List<String> excerptList) {
BigDecimal amortizedCost = new BigDecimal(0);
String extractValue = extractByRegex(excerptList);
if (StringUtils.isEmpty(extractValue)) {
return amortizedCost;
}
// 剔除特殊字符
extractValue = extractValue.replaceAll(" ", "");
extractValue = extractValue.replaceAll(",", "");
extractValue = extractValue.replaceAll("万元", "");
// 判断是否为存数字
if (!extractValue.matches("[0-9]+[.]{0,1}[0-9]*")) {
return amortizedCost;
}
// 设置值
amortizedCost = new BigDecimal(extractValue).setScale(2, BigDecimal.ROUND_HALF_UP);
return amortizedCost;
}
/**
* 提取摊销成本
* @param chapterContents
* @return
*/
public String extractByRegex(List<String> chapterContents) {
String extractField = "";
for (int i = 1; i < chapterContents.size(); i++) {// 从1开始 过滤标题
String line = chapterContents.get(i);
String lineText = Jsoup.parse(line.replaceAll(" ", ""), "UTF-8").text();
// 跳过分页
if ("@@@@".equals(lineText)) {
continue;
}
if (lineText.matches(".*确认总费用预计[为|不超过].*万元.*")) {
Pattern pattern = Pattern.compile("(.*确认总费用预计(为|不超过)(.*万元))");
Matcher matcher = pattern.matcher(lineText);
if (matcher.find() && matcher.groupCount() == 3) {
extractField = matcher.group(3);
}
break;
}
}
return extractField;
}
public static void main(String args[]) {
// String testStr = "假设权益工具的公允价值以董事会审议本期员工持股计划时最近一个交易 日公司股票收盘价 19.58 元/股作为参照,公司应确认总费用预计不超过 5,118.69 万元,该费用由公司在员工持股计划存续期内,按解锁后每次归属比例分摊,计 入相关费用和资本公积,则 2022 年至 2026 年本期员工持股计划费用摊销情况测 算如下:";
// Pattern pattern = Pattern.compile("(.*确认总费用预计(为|不超过)(.*万元))");
// Matcher matcher = pattern.matcher(testStr);
// if (matcher.find()) {
// String collegeId = matcher.group(3);
// System.out.println(collegeId);
// }
String testStr = "六、 对本次发行的推荐意见 .....................................................................................16";
// testStr = testStr.replace(" ", "");
testStr = testStr.replace(".", "");
Pattern pattern = Pattern.compile("[\\d]");
Matcher matcher = pattern.matcher(testStr);
System.out.println(matcher.replaceAll(""));
String content = "第一个解锁期:为自公司公告最后一笔标的股票登记至本持股计划之日起 12 个月后,解锁股份数量为本期员工持股计划所持标的股票总数的 50.00%;20.11, 11";
String regEx="[^0-9.]+";
Pattern pattern1 = Pattern.compile(regEx);
//用定义好的正则表达式拆分字符串,把字符串中的数字留出来
String[] cs = pattern1.split(content);
System.out.println(Arrays.toString(cs) + ((cs.length -1)%2));
content = "1、本持股计划所获标的股票分两期解锁,锁定期分别为 12 个月、24 个月, 均自本持股计划草案经公司股东大会审议通过且公司公告最后一笔标的股票过 户至本持股计划名下之日起计算。锁定期满后,本持股计划所持股票权益将依据 对应考核年度公司业绩解锁,每期解锁比例分别为 50%、50%";
String extractField = "";
pattern = Pattern.compile("^(\\([1-9]|\\([1-9]|\\( [1-9]|[1-9]、|[1-9]).*");
matcher = pattern.matcher(content);
if (matcher.find()) {
extractField = matcher.group(1);
}
System.out.println(extractField);
}
}