PersonService.java 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. package com.iden.bms.service;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.collection.CollUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import com.alibaba.excel.EasyExcel;
  6. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  7. import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
  8. import com.baomidou.mybatisplus.core.metadata.IPage;
  9. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  10. import com.face.monitor.FaceMonitor;
  11. import com.face.monitor.model.FaceModel;
  12. import com.iden.bms.tool.FaceIdenTool;
  13. import com.iden.common.cache.DictCache;
  14. import com.iden.common.cache.FaceMoniterCache;
  15. import com.iden.common.cache.RedisKeyConstant;
  16. import com.iden.common.cache.RedisUtil;
  17. import com.iden.common.constant.Constants;
  18. import com.iden.common.entity.*;
  19. import com.iden.common.enums.CredentialsTypeEnum;
  20. import com.iden.common.enums.GenderEnum;
  21. import com.iden.common.enums.PersonTypeEnum;
  22. import com.iden.common.enums.PopulationTypeEnum;
  23. import com.iden.common.exceltool.RowWriteHandler;
  24. import com.iden.common.exception.BDException;
  25. import com.iden.common.service.*;
  26. import com.iden.common.util.ByteUtil;
  27. import com.iden.common.util.DateUtils;
  28. import com.iden.common.util.ImgUtil;
  29. import com.iden.common.vo.*;
  30. import org.apache.commons.lang3.StringUtils;
  31. import org.apache.logging.log4j.LogManager;
  32. import org.apache.logging.log4j.Logger;
  33. import org.apache.poi.POIXMLDocumentPart;
  34. import org.apache.poi.ss.usermodel.*;
  35. import org.apache.poi.xssf.usermodel.*;
  36. import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
  37. import org.springframework.beans.BeanUtils;
  38. import org.springframework.beans.factory.annotation.Value;
  39. import org.springframework.stereotype.Service;
  40. import org.springframework.transaction.annotation.Transactional;
  41. import org.springframework.web.multipart.MultipartFile;
  42. import javax.annotation.Resource;
  43. import javax.servlet.http.HttpServletResponse;
  44. import java.io.File;
  45. import java.io.FileOutputStream;
  46. import java.net.URL;
  47. import java.net.URLEncoder;
  48. import java.util.*;
  49. /**
  50. *
  51. * @author makejava
  52. * @since 2021-05-21 00:08:38
  53. */
  54. @Service
  55. public class PersonService {
  56. @Resource
  57. private IdenPersonService idenPersonService;
  58. @Resource
  59. private IdenPersonCrowdRefService idenPersonCrowdRefService;
  60. @Resource
  61. private IdenCrowdService idenCrowdService;
  62. @Resource
  63. private IdenCommunityService idenCommunityService;
  64. @Resource
  65. private IdenWarningPersonService idenWarningPersonService;
  66. @Resource
  67. private RedisUtil redisUtil;
  68. @Value("${iden.root:#{null}}")
  69. private String idenRoot;
  70. @Value("${file.url:#{null}}")
  71. private String fileUrl;
  72. private static final Logger logger = LogManager.getLogger(PersonService.class);
  73. public PersonStaVO getPersonStaVO(String type, String nameOrCred, String district, String subdistrict, Long communityId, Long crowdId, String address, String gender, String populationType, UserLoginedConvertVO loginUser) {
  74. QueryWrapper<IdenPerson> queryWrapper = new QueryWrapper<>();
  75. queryWrapper.lambda().like(IdenPerson::getType,type)
  76. .like(StrUtil.isNotEmpty(address), IdenPerson::getAddress,address)
  77. .eq(StrUtil.isNotEmpty(gender),IdenPerson::getGender,gender)
  78. .eq(StrUtil.isNotEmpty(populationType),IdenPerson::getPopulationType,populationType)
  79. .eq(StrUtil.isNotEmpty(district),IdenPerson::getDistrict,district)
  80. .eq(StrUtil.isNotEmpty(subdistrict),IdenPerson::getSubdistrict,subdistrict)
  81. .eq(communityId != null,IdenPerson::getCommunityId,communityId)
  82. .and(StrUtil.isNotEmpty(nameOrCred),wrapper -> wrapper.like(IdenPerson::getName,nameOrCred)
  83. .or().like(IdenPerson::getCredentialsCode,nameOrCred));
  84. Integer personCount = this.idenPersonService.count(queryWrapper);
  85. QueryWrapper<IdenPerson> queryWrapper1 = new QueryWrapper<>();
  86. queryWrapper1.lambda().like(IdenPerson::getType,type)
  87. .like(StrUtil.isNotEmpty(address), IdenPerson::getAddress,address)
  88. .eq(StrUtil.isNotEmpty(gender),IdenPerson::getGender,gender)
  89. .eq(StrUtil.isNotEmpty(populationType),IdenPerson::getPopulationType,populationType)
  90. .eq(StrUtil.isNotEmpty(district),IdenPerson::getDistrict,district)
  91. .eq(StrUtil.isNotEmpty(subdistrict),IdenPerson::getSubdistrict,subdistrict)
  92. .eq(communityId != null,IdenPerson::getCommunityId,communityId)
  93. .and(StrUtil.isNotEmpty(nameOrCred),wrapper -> wrapper.like(IdenPerson::getName,nameOrCred)
  94. .or().like(IdenPerson::getCredentialsCode,nameOrCred))
  95. .isNotNull(IdenPerson::getImage);
  96. Integer faceImageCount = this.idenPersonService.count(queryWrapper1);
  97. QueryWrapper<IdenPerson> queryWrapper2 = new QueryWrapper<>();
  98. queryWrapper2.select("distinct community_id")
  99. .lambda().like(IdenPerson::getType,type)
  100. .like(StrUtil.isNotEmpty(address), IdenPerson::getAddress,address)
  101. .eq(StrUtil.isNotEmpty(gender),IdenPerson::getGender,gender)
  102. .eq(StrUtil.isNotEmpty(populationType),IdenPerson::getPopulationType,populationType)
  103. .eq(StrUtil.isNotEmpty(district),IdenPerson::getDistrict,district)
  104. .eq(StrUtil.isNotEmpty(subdistrict),IdenPerson::getSubdistrict,subdistrict)
  105. .eq(communityId != null,IdenPerson::getCommunityId,communityId)
  106. .and(StrUtil.isNotEmpty(nameOrCred),wrapper -> wrapper.like(IdenPerson::getName,nameOrCred)
  107. .or().like(IdenPerson::getCredentialsCode,nameOrCred));
  108. Integer communityCount = this.idenPersonService.count(queryWrapper2);
  109. PersonStaVO vo = new PersonStaVO();
  110. vo.setCommunityCount(communityCount);
  111. vo.setFaceImageCount(faceImageCount);
  112. vo.setPersonCount(personCount);
  113. return vo;
  114. }
  115. /**
  116. * 查询人员列表
  117. * @return
  118. */
  119. public IPage<PersonVO> listPerson(String type, String nameOrCred, String district, String subdistrict, Long communityId, Long crowdId, String address, String gender, String populationType, UserLoginedConvertVO loginUser, PageReqVO pageReqVo) {
  120. IPage<IdenPerson> page = new Page<>(pageReqVo.getCurrent(), pageReqVo.getPageSize());
  121. QueryWrapper<IdenPerson> queryWrapper = new QueryWrapper<>();
  122. queryWrapper.lambda().like(IdenPerson::getType,type)
  123. .like(StrUtil.isNotEmpty(address), IdenPerson::getAddress,address)
  124. .eq(StrUtil.isNotEmpty(gender),IdenPerson::getGender,gender)
  125. .eq(StrUtil.isNotEmpty(populationType),IdenPerson::getPopulationType,populationType)
  126. .eq(StrUtil.isNotEmpty(district),IdenPerson::getDistrict,district)
  127. .eq(StrUtil.isNotEmpty(subdistrict),IdenPerson::getSubdistrict,subdistrict)
  128. .eq(communityId != null,IdenPerson::getCommunityId,communityId)
  129. .and(StrUtil.isNotEmpty(nameOrCred),wrapper -> wrapper.like(IdenPerson::getName,nameOrCred)
  130. .or().like(IdenPerson::getCredentialsCode,nameOrCred))
  131. .orderByDesc(IdenPerson::getModifyTime)
  132. .orderByDesc(IdenPerson::getCreateTime);
  133. if (crowdId != null) {
  134. queryWrapper.apply(" iden_person.id in ( select person_id from iden_person_crowd_ref ipcr where ipcr.crowd_id = "+ crowdId + ")");
  135. }
  136. IPage<IdenPerson> pageRes = this.idenPersonService.page(page, queryWrapper);
  137. IPage<PersonVO> results = new Page<>(pageRes.getCurrent(),pageRes.getSize(),pageRes.getTotal());
  138. if(CollUtil.isNotEmpty(pageRes.getRecords())){
  139. List<PersonVO> list = new ArrayList<>();
  140. pageRes.getRecords().forEach(item -> {
  141. PersonVO resVO = new PersonVO();
  142. BeanUtils.copyProperties(item,resVO);
  143. resVO.setPopulationTypeName(PopulationTypeEnum.getValueToName(resVO.getPopulationType()));
  144. resVO.setTypeName(PersonTypeEnum.getValueToName(resVO.getType()));
  145. resVO.setGenderName(GenderEnum.getValueToName(resVO.getGender()));
  146. resVO.setCredentialsTypeName(CredentialsTypeEnum.getValueToName(resVO.getCredentialsType()));
  147. resVO.setMarriageName(DictCache.getNameByValue("marriage", resVO.getMarriage()));
  148. resVO.setPolicitalStatusName(DictCache.getNameByValue("policital_status", resVO.getPolicitalStatus()));
  149. Long communityId1 = resVO.getCommunityId();
  150. if(communityId1 != null){
  151. IdenCommunity idenCommunity = this.idenCommunityService.getById(communityId1);
  152. if(idenCommunity != null) {
  153. resVO.setCommunityName(idenCommunity.getName());
  154. }
  155. }
  156. QueryWrapper<IdenPersonCrowdRef> queryWrapper1 = new QueryWrapper<>();
  157. queryWrapper1.lambda().eq(IdenPersonCrowdRef::getPersonId,resVO.getId());
  158. List<IdenPersonCrowdRef> listIdenPersonCrowdRef = idenPersonCrowdRefService.list(queryWrapper1);
  159. StringBuilder sb = new StringBuilder();
  160. if (CollUtil.isNotEmpty(listIdenPersonCrowdRef)) {
  161. for(IdenPersonCrowdRef idenPersonCrowdRef : listIdenPersonCrowdRef){
  162. IdenCrowd idenCrowd = idenCrowdService.getById(idenPersonCrowdRef.getCrowdId());
  163. if(idenCrowd != null) {
  164. sb.append(idenCrowd.getName()).append(",");
  165. }
  166. }
  167. }
  168. String crowdName = sb.toString();
  169. if(crowdName != null && crowdName.endsWith(",")) {
  170. crowdName = crowdName.substring(0, crowdName.length() - 1);
  171. }
  172. resVO.setCrowdName(crowdName);
  173. list.add(resVO);
  174. });
  175. results.setRecords(list);
  176. }
  177. return results;
  178. }
  179. public void downloadFormwork(UserLoginedConvertVO loginUser, HttpServletResponse response) throws Exception {
  180. List<PersonExcelVO> records = new ArrayList<>();
  181. try {
  182. response.reset(); // 非常重要
  183. response.addHeader("Access-Control-Allow-Origin", "*");
  184. response.setContentType("application/vnd.ms-excel");
  185. response.setCharacterEncoding("utf-8");
  186. final String fileName = URLEncoder.encode("Person", "UTF-8");
  187. response.setHeader("Content-disposition", "attachment;filename=" + fileName + "_" + System.currentTimeMillis() + ".xlsx");
  188. EasyExcel.write(response.getOutputStream(), PersonExcelVO.class).sheet("人员表").registerWriteHandler(new RowWriteHandler()).doWrite(records);
  189. } catch (Exception e) {
  190. e.printStackTrace();
  191. }
  192. }
  193. public void exportToExcel(String type, String nameOrCred, String district, String subdistrict, Long communityId, Long crowdId, String address, String gender, String populationType, UserLoginedConvertVO loginUser, HttpServletResponse response) throws Exception {
  194. QueryWrapper<IdenPerson> queryWrapper = new QueryWrapper<>();
  195. queryWrapper.lambda().like(IdenPerson::getType,type)
  196. .like(StrUtil.isNotEmpty(address), IdenPerson::getAddress,address)
  197. .eq(StrUtil.isNotEmpty(gender),IdenPerson::getGender,gender)
  198. .eq(StrUtil.isNotEmpty(populationType),IdenPerson::getPopulationType,populationType)
  199. .eq(StrUtil.isNotEmpty(district),IdenPerson::getDistrict,district)
  200. .eq(StrUtil.isNotEmpty(subdistrict),IdenPerson::getSubdistrict,subdistrict)
  201. .eq(communityId != null,IdenPerson::getCommunityId,communityId)
  202. .and(StrUtil.isNotEmpty(nameOrCred),wrapper -> wrapper.like(IdenPerson::getName,nameOrCred)
  203. .or().like(IdenPerson::getCredentialsCode,nameOrCred))
  204. .orderByDesc(IdenPerson::getModifyTime)
  205. .orderByDesc(IdenPerson::getCreateTime);
  206. if (crowdId != null) {
  207. queryWrapper.apply(" in ( select person_id from iden_person_crowd_ref ipcr where ipcr.crowd_id = "+ crowdId + ")");
  208. }
  209. List<IdenPerson> list = this.idenPersonService.list(queryWrapper);
  210. List<PersonExcelVO> records = new ArrayList<>();
  211. if (CollUtil.isNotEmpty(list)) {
  212. list.forEach(item->{
  213. PersonExcelVO resVO = new PersonExcelVO();
  214. BeanUtils.copyProperties(item,resVO);
  215. resVO.setPopulationTypeName(PopulationTypeEnum.getValueToName(item.getPopulationType()));
  216. resVO.setTypeName(PersonTypeEnum.getValueToName(item.getType()));
  217. resVO.setGenderName(GenderEnum.getValueToName(item.getGender()));
  218. resVO.setCredentialsTypeName(CredentialsTypeEnum.getValueToName(item.getCredentialsType()));
  219. resVO.setMarriageName(DictCache.getNameByValue("marriage", item.getMarriage()));
  220. resVO.setPolicitalStatusName(DictCache.getNameByValue("policital_status", item.getPolicitalStatus()));
  221. try {
  222. resVO.setImageUrl(new URL(item.getImage()));
  223. } catch (Exception e){
  224. e.printStackTrace();
  225. }
  226. Long communityId1 = item.getCommunityId();
  227. if(communityId1 != null){
  228. IdenCommunity idenCommunity = this.idenCommunityService.getById(communityId1);
  229. if(idenCommunity != null) {
  230. resVO.setCommunityName(idenCommunity.getName());
  231. }
  232. }
  233. QueryWrapper<IdenPersonCrowdRef> queryWrapper1 = new QueryWrapper<>();
  234. queryWrapper1.lambda().eq(IdenPersonCrowdRef::getPersonId,item.getId());
  235. List<IdenPersonCrowdRef> listIdenPersonCrowdRef = idenPersonCrowdRefService.list(queryWrapper1);
  236. StringBuilder sb = new StringBuilder();
  237. if (CollUtil.isNotEmpty(listIdenPersonCrowdRef)) {
  238. for(IdenPersonCrowdRef idenPersonCrowdRef : listIdenPersonCrowdRef){
  239. IdenCrowd idenCrowd = idenCrowdService.getById(idenPersonCrowdRef.getCrowdId());
  240. if(idenCrowd != null) {
  241. sb.append(idenCrowd.getName()).append(",");
  242. }
  243. }
  244. }
  245. String crowdName = sb.toString();
  246. if(crowdName != null && crowdName.endsWith(",")) {
  247. crowdName = crowdName.substring(0, crowdName.length() - 1);
  248. }
  249. resVO.setCrowdName(crowdName);
  250. records.add(resVO);
  251. });
  252. }
  253. try {
  254. response.reset(); // 非常重要
  255. response.addHeader("Access-Control-Allow-Origin", "*");
  256. response.setContentType("application/vnd.ms-excel");
  257. response.setCharacterEncoding("utf-8");
  258. final String fileName = URLEncoder.encode("Person", "UTF-8");
  259. response.setHeader("Content-disposition", "attachment;filename=" + fileName + "_" + System.currentTimeMillis() + ".xlsx");
  260. EasyExcel.write(response.getOutputStream(), PersonExcelVO.class).sheet("人员表").registerWriteHandler(new RowWriteHandler()).doWrite(records);
  261. } catch (Exception e) {
  262. e.printStackTrace();
  263. }
  264. }
  265. /**
  266. * 导入
  267. * @param file
  268. * @return
  269. * @throws Exception
  270. */
  271. @Transactional(rollbackFor = Exception.class)
  272. public List<Long> importWithExcel(MultipartFile file) throws BDException {
  273. List<Long> personIdList = new ArrayList<>();
  274. try {
  275. String excelFileName = file.getOriginalFilename();
  276. logger.info("excelFileName ==" + excelFileName);
  277. if (!excelFileName.substring(excelFileName.length() - 4).equals("xlsx")) {
  278. throw new BDException("导入Excel只支持xlsx格式");
  279. }
  280. XSSFWorkbook workBook = new XSSFWorkbook(file.getInputStream());
  281. Sheet sheet = workBook.getSheetAt(0);
  282. if (sheet.getLastRowNum() == 0) {
  283. logger.error("表中无数据!");
  284. throw new BDException("表中无数据");
  285. }
  286. //图片对应的行和图片数据
  287. Map<Integer, PictureData> picMap = new HashMap<>();
  288. //读取sheet的图片放入Map
  289. for (POIXMLDocumentPart dr : ((XSSFSheet) sheet).getRelations()) {
  290. if (dr instanceof XSSFDrawing) {
  291. XSSFDrawing drawing = (XSSFDrawing) dr;
  292. List<XSSFShape> shapes = drawing.getShapes();
  293. for (XSSFShape shape : shapes) {
  294. XSSFPicture pic = (XSSFPicture) shape;
  295. //获取图片格式
  296. String ext = pic.getPictureData().suggestFileExtension();
  297. logger.info("ext == " + ext);
  298. if(!"jpg".equalsIgnoreCase(ext) && !"jpeg".equalsIgnoreCase(ext) && !"png".equalsIgnoreCase(ext) ){
  299. throw new BDException("Excel中只能放jpg或png格式图像");
  300. }
  301. XSSFClientAnchor anchor = pic.getPreferredSize();
  302. CTMarker ctMarker = anchor.getFrom();
  303. int row = ctMarker.getRow();
  304. picMap.put(row, pic.getPictureData());
  305. }
  306. }
  307. }
  308. //定义数据集合存放excel所有数据
  309. List<PersonVO> personVOList = new ArrayList<>();
  310. //遍历行
  311. for (int i = 1; i <= sheet.getLastRowNum(); i++) {
  312. logger.info("sheet.getLastRowNum() ==" + sheet.getLastRowNum());
  313. //错误提示消息
  314. StringBuffer msg = new StringBuffer();
  315. Row row = sheet.getRow(i);
  316. if (null == row)
  317. continue;
  318. PersonVO personVO = new PersonVO();
  319. IdenCommunity idenCommunity = null;
  320. // 遍历列
  321. for (int j = 0; j < 23; j++) {
  322. Cell cell = row.getCell(j);
  323. String value = null;
  324. if (null != cell) {
  325. //全部作为文本处理
  326. //cell.setCellType(HSSFCell.CELL_TYPE_STRING);
  327. value = cell.getStringCellValue();
  328. }
  329. if (0 == j) {//人员编码
  330. if (StringUtils.isNotBlank(value)){
  331. personVO.setCode(value);
  332. }
  333. } else if (1 == j) {//姓名
  334. if (StringUtils.isNotBlank(value)){
  335. personVO.setName(value);
  336. }else {
  337. msg.append("请填写姓名!\n");
  338. }
  339. } else if (3 == j) {//性别
  340. if (StringUtils.isNotBlank(value)) {
  341. personVO.setGender(GenderEnum.getNameToValue(value));
  342. }
  343. } else if (4 == j) {//证件类型
  344. if (StringUtils.isNotBlank(value)){
  345. personVO.setCredentialsType(CredentialsTypeEnum.getNameToValue(value));
  346. }
  347. } else if (5 == j) {//证件号码
  348. if (StringUtils.isNotBlank(value)){
  349. personVO.setCredentialsCode(value);
  350. }
  351. } else if (6 == j) {//手机号码
  352. if (StringUtils.isNotBlank(value)){
  353. personVO.setPhone(value);
  354. }
  355. } else if (7 == j) {//人口类型
  356. if (StringUtils.isNotBlank(value)){
  357. personVO.setPopulationType(PopulationTypeEnum.getNameToValue(value));
  358. }
  359. } else if (8 == j) {//民族
  360. if (StringUtils.isNotBlank(value)){
  361. personVO.setNation(value);
  362. }
  363. } else if (9 == j) {//政治面貌
  364. if (StringUtils.isNotBlank(value)){
  365. personVO.setPolicitalStatus(DictCache.getValueByName("policital_status",value));
  366. }
  367. } else if (10 == j) {//婚姻
  368. if (StringUtils.isNotBlank(value)){
  369. personVO.setMarriage(DictCache.getValueByName("marriage",value));
  370. }
  371. } else if (11 == j) {//口音
  372. if (StringUtils.isNotBlank(value)){
  373. personVO.setVoice(value);
  374. }
  375. } else if (12 == j) {//所属区域
  376. if (StringUtils.isNotBlank(value)){
  377. personVO.setDistrict(value);
  378. }
  379. } else if (13 == j) {//所属街道
  380. if (StringUtils.isNotBlank(value)){
  381. personVO.setSubdistrict(value);
  382. }
  383. } else if (14== j) {//所属小区
  384. if (StringUtils.isNotBlank(value)){
  385. logger.info("小区名字==" + value);
  386. QueryWrapper<IdenCommunity> queryWrapper = new QueryWrapper<>();
  387. queryWrapper.lambda().eq(IdenCommunity::getName,value);
  388. idenCommunity = this.idenCommunityService.getOne(queryWrapper);
  389. logger.info("idenCommunity ==" + idenCommunity);
  390. if(idenCommunity != null){
  391. personVO.setCommunityId(idenCommunity.getId());
  392. } else {
  393. msg.append("填写所属小区名称不存在!\n");
  394. }
  395. }else {
  396. msg.append("请填写所属小区!\n");
  397. }
  398. } else if (15 == j) {//地址
  399. if (StringUtils.isNotBlank(value)){
  400. personVO.setAddress(value);
  401. }
  402. } else if (16 == j) {//工作单位
  403. if (StringUtils.isNotBlank(value)){
  404. personVO.setWorkPlace(value);
  405. }
  406. } else if (17 == j) {//单位地址
  407. if (StringUtils.isNotBlank(value)){
  408. personVO.setWorkAddress(value);
  409. }
  410. } else if (18 == j) {//类型
  411. if (StringUtils.isNotBlank(value)){
  412. logger.info("类型==" + value);
  413. String type = PersonTypeEnum.getNameToValue(value);
  414. logger.info("type==" + type);
  415. if(StringUtils.isEmpty(type)){
  416. msg.append("请填写类型(重点人员或小区人员,多个用英文逗号分隔)!\n");
  417. } else {
  418. personVO.setType(type);
  419. }
  420. } else {
  421. msg.append("请填写类型(重点人员或小区人员,多个用英文逗号分隔)!\n");
  422. }
  423. } else if (19 == j) {//人群类型
  424. if (StringUtils.isNotBlank(value)){
  425. String[] crowdNames = value.split(",");
  426. List<Long> idenCrowdIds = new ArrayList<>();
  427. for (String crowdName : crowdNames) {
  428. QueryWrapper<IdenCrowd> queryWrapper = new QueryWrapper<>();
  429. queryWrapper.lambda().eq(IdenCrowd::getName,crowdName);
  430. IdenCrowd idenCrowd = this.idenCrowdService.getOne(queryWrapper);
  431. if(idenCrowd == null){
  432. msg.append("填写人群类型错误(多个用英文逗号分隔)!\n");
  433. idenCrowdIds.clear();
  434. break;
  435. } else{
  436. idenCrowdIds.add(idenCrowd.getId());
  437. }
  438. }
  439. if(CollUtil.isNotEmpty(idenCrowdIds)){
  440. personVO.setCrowdIds(idenCrowdIds);
  441. }
  442. }
  443. } else if (20 == j) {//备注
  444. if (StringUtils.isNotBlank(value)){
  445. personVO.setRemark(value);
  446. }
  447. }
  448. if (!StringUtils.isBlank(msg.toString())) {
  449. logger.error("第 " + i + " 行: " + msg.toString());
  450. throw new BDException("第 " + i + " 行: " + msg.toString());
  451. }
  452. }
  453. PictureData picData = picMap.get(i);
  454. if(picData != null){
  455. //保存的文件名
  456. String saveFileName = DateUtils.getCurrYyyyMMddHHmmssDate() + "_" + UUID.randomUUID().toString() + "." + picData.suggestFileExtension();
  457. logger.info("saveFileName== " + saveFileName);
  458. String savePath = idenRoot + "data/final/person/image/" + idenCommunity.getCode() + "/" + saveFileName;
  459. // 保存图片
  460. savePic(picData,savePath);
  461. personVO.setImage(fileUrl + "person/image/" + idenCommunity.getCode() +"/" + saveFileName);
  462. }
  463. String image = personVO.getImage();
  464. if(StringUtils.isNotEmpty(image)) {
  465. String featPtr = idenFeatPtr(image,idenCommunity.getCode());
  466. if(StringUtils.isNotEmpty(featPtr)) {
  467. personVO.setFeatPtr(featPtr);
  468. } else {
  469. throw new BDException("图像识别失败,请上传正确人脸图像");
  470. }
  471. }
  472. personVOList.add(personVO);
  473. }
  474. if (CollUtil.isNotEmpty(personVOList)) {
  475. List<IdenPersonCrowdRef> idenPersonCrowdRefList = new ArrayList<>();
  476. personVOList.forEach(item->{
  477. IdenPerson idenPerson = new IdenPerson();
  478. BeanUtil.copyProperties(item,idenPerson);
  479. idenPerson.setUid(UUID.randomUUID().toString());
  480. idenPerson.setCreateTime(new Date());
  481. idenPersonService.save(idenPerson);
  482. appendFaceDataset(idenPerson);
  483. personIdList.add(idenPerson.getId());
  484. List<Long> crowdIds = item.getCrowdIds();
  485. if(CollUtil.isNotEmpty(crowdIds)){
  486. crowdIds.forEach(item1 ->{
  487. IdenPersonCrowdRef idenPersonCrowdRef = new IdenPersonCrowdRef();
  488. idenPersonCrowdRef.setCrowdId(item1);
  489. idenPersonCrowdRef.setPersonId(idenPerson.getId());
  490. idenPersonCrowdRefList.add(idenPersonCrowdRef);
  491. });
  492. }
  493. });
  494. if(CollUtil.isNotEmpty(idenPersonCrowdRefList)){
  495. //批量保存
  496. this.idenPersonCrowdRefService.saveBatch(idenPersonCrowdRefList);
  497. }
  498. }
  499. } catch (Exception e) {
  500. logger.error("导入异常", e);
  501. e.printStackTrace();
  502. throw new BDException("导入异常:" + e.getMessage());
  503. }
  504. return personIdList;
  505. }
  506. private void savePic( PictureData picData,String savePath) throws Exception {
  507. byte[] data = picData.getData();
  508. FileOutputStream out = new FileOutputStream(savePath);
  509. out.write(data);
  510. out.close();
  511. }
  512. /**
  513. * 删除人员
  514. * @param id
  515. * @return
  516. */
  517. @Transactional(rollbackFor = Exception.class)
  518. public void deleteById(Long id) throws BDException {
  519. String key = RedisKeyConstant.PERSON_DELETE;
  520. String requestId = UUID.randomUUID().toString();
  521. boolean result = redisUtil.tryLock(key,requestId,10 * 60);
  522. try {
  523. if (result) {
  524. QueryWrapper<IdenWarningPerson> queryWrapper0 = new QueryWrapper<>();
  525. queryWrapper0.lambda().eq(IdenWarningPerson::getPersonId,id);
  526. int cnt = this.idenWarningPersonService.count(queryWrapper0);
  527. if(cnt > 0){
  528. throw new BDException("人员被引用,不能删除");
  529. }
  530. IdenPerson idenPerson = this.idenPersonService.getById(id);
  531. QueryWrapper<IdenPersonCrowdRef> queryWrapper = new QueryWrapper<>();
  532. queryWrapper.lambda().eq(IdenPersonCrowdRef::getPersonId,idenPerson.getId());
  533. idenPersonCrowdRefService.remove(queryWrapper);
  534. String image = idenPerson.getImage();
  535. IdenCommunity idenCommunity = this.idenCommunityService.getById(idenPerson.getCommunityId());
  536. if (StringUtils.isNotEmpty(image) && idenCommunity != null) {
  537. File imageFile = new File(idenRoot + "data/final/person/image/" + idenCommunity.getCode() + "/" + image.substring(image.lastIndexOf("/")));
  538. if(imageFile.exists()){
  539. imageFile.delete();
  540. }
  541. }
  542. this.idenPersonService.removeById(id);
  543. reloadFaceDataset();
  544. } else {
  545. throw new BDException("不能多人同时删除,稍后再试");
  546. }
  547. } catch (Exception e) {
  548. e.getMessage();
  549. } finally {
  550. redisUtil.releaseLock(key,requestId);
  551. }
  552. }
  553. /**
  554. * 详情
  555. * @param id
  556. * @return
  557. */
  558. public PersonVO getPersonById(Long id){
  559. IdenPerson idenPerson = this.idenPersonService.getById(id);
  560. if (idenPerson!=null){
  561. PersonVO resVO = new PersonVO();
  562. BeanUtil.copyProperties(idenPerson,resVO);
  563. resVO.setPopulationTypeName(PopulationTypeEnum.getValueToName(resVO.getPopulationType()));
  564. resVO.setTypeName(PersonTypeEnum.getValueToName(resVO.getType()));
  565. resVO.setMarriageName(DictCache.getNameByValue("marriage", resVO.getMarriage()));
  566. resVO.setPolicitalStatusName(DictCache.getNameByValue("policital_status", resVO.getPolicitalStatus()));
  567. QueryWrapper<IdenPersonCrowdRef> queryWrapper1 = new QueryWrapper<>();
  568. queryWrapper1.lambda().eq(IdenPersonCrowdRef::getPersonId,resVO.getId());
  569. List<IdenPersonCrowdRef> listIdenPersonCrowdRef = idenPersonCrowdRefService.list(queryWrapper1);
  570. StringBuilder sb = new StringBuilder();
  571. if (CollUtil.isNotEmpty(listIdenPersonCrowdRef)) {
  572. for(IdenPersonCrowdRef idenPersonCrowdRef : listIdenPersonCrowdRef){
  573. IdenCrowd idenCrowd = idenCrowdService.getById(idenPersonCrowdRef.getCrowdId());
  574. if(idenCrowd != null) {
  575. sb.append(idenCrowd.getName()).append(",");
  576. }
  577. }
  578. }
  579. String crowdName = sb.toString();
  580. if(crowdName != null && crowdName.endsWith(",")) {
  581. crowdName = crowdName.substring(0, crowdName.length() - 1);
  582. }
  583. resVO.setCrowdName(crowdName);
  584. return resVO;
  585. }
  586. return null;
  587. }
  588. /**
  589. * 上传图像
  590. * @param file
  591. * @return 访问URL
  592. */
  593. public String uploadImage(MultipartFile file,Long communityId) throws BDException {
  594. if(communityId == null ){
  595. throw new BDException("必须选择小区");
  596. }
  597. IdenCommunity idenCommunity = this.idenCommunityService.getById(communityId);
  598. if(idenCommunity == null ){
  599. throw new BDException("小区不能为空");
  600. }
  601. String image = null;
  602. try {
  603. if (file != null) {
  604. //获取文件名
  605. String fileName = file.getOriginalFilename();
  606. if (org.springframework.util.StringUtils.isEmpty(fileName) || file.getSize() == 0) {
  607. throw new BDException("图像文件不能为空!");
  608. }
  609. //验证文件名是否合格
  610. if (!ImgUtil.isImg(fileName)) {
  611. throw new BDException("图像文件必须是图片格式!");
  612. }
  613. String saveFileName = DateUtils.getCurrYyyyMMddHHmmssDate() + "_" + UUID.randomUUID().toString() + fileName.substring(fileName.lastIndexOf("."), fileName.length());
  614. String uploadDir = idenRoot + "data/final/person/image/" + idenCommunity.getCode() + "/";
  615. File uploadDirFile = new File(uploadDir);
  616. if (!uploadDirFile.exists()){
  617. uploadDirFile.mkdirs();
  618. }
  619. FileOutputStream fos = new FileOutputStream(uploadDir + saveFileName);
  620. fos.write(file.getBytes());
  621. image = fileUrl + "person/image/" + idenCommunity.getCode() +"/"+ saveFileName;
  622. } else {
  623. throw new BDException("上传失败");
  624. }
  625. } catch (Exception e) {
  626. e.printStackTrace();
  627. throw new BDException("上传失败",e);
  628. }
  629. return image;
  630. }
  631. /**
  632. * 保存人员
  633. * 一个人只属于一个小区,避免同一个自然人属于二个小区
  634. * @param vo
  635. */
  636. @Transactional(rollbackFor = Exception.class)
  637. public void createPerson(PersonVO vo, UserLoginedConvertVO loginUser) throws BDException {
  638. Long communityId = vo.getCommunityId();
  639. if(communityId == null ){
  640. throw new BDException("必须选择小区");
  641. }
  642. IdenCommunity idenCommunity = this.idenCommunityService.getById(communityId);
  643. if(idenCommunity == null ){
  644. throw new BDException("小区不能为空");
  645. }
  646. //保存人员
  647. IdenPerson idenPerson = new IdenPerson();
  648. BeanUtil.copyProperties(vo,idenPerson);
  649. idenPerson.setUid(UUID.randomUUID().toString());
  650. idenPerson.setCreateTime(new Date());
  651. //识别
  652. String image = idenPerson.getImage();
  653. if(StringUtils.isNotEmpty(image)) {
  654. String featPtr = idenFeatPtr(image,idenCommunity.getCode());
  655. if(StringUtils.isNotEmpty(featPtr)) {
  656. idenPerson.setFeatPtr(featPtr);
  657. } else {
  658. throw new BDException("图像识别失败,请上传正确人脸图像");
  659. }
  660. }
  661. this.idenPersonService.save(idenPerson);
  662. appendFaceDataset(idenPerson);
  663. }
  664. private void appendFaceDataset(IdenPerson idenPerson){
  665. //追加陌生人脸库缓存
  666. FaceMonitor faceMonitorPerson = FaceMoniterCache.getFaceMonitor(Constants.FACE_CACHE_PERSON_KEY);
  667. FaceModel[] dataset = new FaceModel[1];
  668. dataset[0] = new FaceModel();
  669. dataset[0].setPersonId(idenPerson.getId().intValue());
  670. dataset[0].setName(idenPerson.getUid());
  671. dataset[0].setFeatValue(ByteUtil.hex2Byte(idenPerson.getFeatPtr()));
  672. faceMonitorPerson.appendFaceDataset(dataset);
  673. }
  674. private void reloadFaceDataset(){
  675. //重新加载人脸库缓存
  676. FaceMonitor faceMonitorPerson = FaceMoniterCache.getFaceMonitor(Constants.FACE_CACHE_PERSON_KEY);
  677. QueryWrapper<IdenPerson> queryWrapper = new QueryWrapper();
  678. queryWrapper.select("id","name","feat_ptr");
  679. queryWrapper.lambda().isNotNull(IdenPerson::getFeatPtr);
  680. List<IdenPerson> idenPersonList = idenPersonService.list(queryWrapper);
  681. if (CollUtil.isNotEmpty(idenPersonList)) {
  682. FaceModel[] dataset = new FaceModel[idenPersonList.size()];
  683. for(int i = 0; i < idenPersonList.size(); i++){
  684. IdenPerson idenPerson = idenPersonList.get(i);
  685. dataset[i] = new FaceModel();
  686. dataset[i].setPersonId(idenPerson.getId().intValue());
  687. dataset[i].setName(idenPerson.getUid());
  688. dataset[i].setFeatValue(ByteUtil.hex2Byte(idenPerson.getFeatPtr()));
  689. }
  690. faceMonitorPerson.loadFaceDataset(dataset);
  691. }
  692. }
  693. /**
  694. * 修改人员
  695. * @param vo
  696. */
  697. @Transactional(rollbackFor = Exception.class)
  698. public void updatePerson(PersonVO vo) throws BDException {
  699. String key = RedisKeyConstant.PERSON_UPDATE;
  700. String requestId = UUID.randomUUID().toString();
  701. boolean result = redisUtil.tryLock(key,requestId,10 * 60);
  702. try {
  703. if (result) {
  704. vo.setCommunityId(null);//不能修改小区
  705. IdenPerson idenPerson = this.idenPersonService.getById(vo.getId());
  706. Long communityId = idenPerson.getCommunityId();
  707. IdenCommunity idenCommunity = this.idenCommunityService.getById(communityId);
  708. //保存人员
  709. String oldImage = idenPerson.getImage();
  710. BeanUtil.copyProperties(vo,idenPerson);
  711. String newImage = vo.getImage();
  712. if (StringUtils.isNotEmpty(newImage) && !newImage.equals(oldImage)){
  713. //识别
  714. String fileNameNew = newImage.substring(newImage.lastIndexOf("/"));
  715. File imgFileNew = new File(idenRoot + "data/final/person/image/" + idenCommunity.getCode() + "/" + fileNameNew);
  716. String featPtr = FaceIdenTool.getFeatPtr(idenRoot,imgFileNew);
  717. if (FaceIdenTool.isBad(featPtr)){
  718. File discardDir = new File(imgFileNew.getParentFile().getAbsolutePath().replace("final","discard"));
  719. if(!discardDir.exists()){
  720. discardDir.mkdirs();
  721. }
  722. File discardImgFile = new File(discardDir, fileNameNew);
  723. imgFileNew.renameTo(discardImgFile);//移动到废弃目录
  724. throw new BDException("图像识别失败,请上传正确人脸图像");
  725. }
  726. idenPerson.setFeatPtr(featPtr);
  727. // 删除老的文件
  728. if(StringUtils.isNotEmpty(oldImage)){
  729. String fileNameOld = oldImage.substring(oldImage.lastIndexOf("/"));
  730. File imgFileOld = new File(idenRoot + "data/final/person/image/" + idenCommunity.getCode() + "/" + fileNameOld);
  731. if(imgFileOld.exists()){
  732. imgFileOld.delete();
  733. }
  734. }
  735. }
  736. idenPerson.setModifyTime(new Date());
  737. this.idenPersonService.updateById(idenPerson);
  738. reloadFaceDataset();
  739. } else {
  740. throw new BDException("不能多人同时修改,稍后再试");
  741. }
  742. } catch (Exception e) {
  743. e.getMessage();
  744. } finally {
  745. redisUtil.releaseLock(key,requestId);
  746. }
  747. }
  748. /**
  749. * 修改人员
  750. * @param vo
  751. */
  752. @Transactional(rollbackFor = Exception.class)
  753. public void updateRemark(PersonVO vo) throws BDException {
  754. UpdateWrapper<IdenPerson> updateWrapper = new UpdateWrapper();
  755. updateWrapper.lambda().set(IdenPerson::getRemark,vo.getRemark())
  756. .eq(IdenPerson::getId,vo.getId());
  757. this.idenPersonService.update(updateWrapper);
  758. }
  759. private String idenFeatPtr(String image,String communityCode) {
  760. String fileName = image.substring(image.lastIndexOf("/"));
  761. File imgFile = new File(idenRoot + "data/final/person/image/"+ communityCode + "/" + fileName);
  762. String featPtr = FaceIdenTool.getFeatPtr(idenRoot,imgFile);
  763. if (FaceIdenTool.isBad(featPtr)) {
  764. File discardDir = new File(imgFile.getParentFile().getAbsolutePath().replace("final","discard"));
  765. if(!discardDir.exists()){
  766. discardDir.mkdirs();
  767. }
  768. File discardImgFile = new File(discardDir, fileName);
  769. imgFile.renameTo(discardImgFile);//移动到废弃目录
  770. featPtr = null;
  771. }
  772. return featPtr;
  773. }
  774. }