PositionController.java 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. package jnpf.permission.controller;
  2. import cn.dev33.satoken.annotation.SaCheckPermission;
  3. import cn.hutool.core.collection.CollectionUtil;
  4. import io.swagger.v3.oas.annotations.Operation;
  5. import io.swagger.v3.oas.annotations.Parameter;
  6. import io.swagger.v3.oas.annotations.Parameters;
  7. import io.swagger.v3.oas.annotations.tags.Tag;
  8. import jakarta.validation.Valid;
  9. import jnpf.base.ActionResult;
  10. import jnpf.base.controller.SuperController;
  11. import jnpf.base.service.SysconfigService;
  12. import jnpf.base.util.ExcelTool;
  13. import jnpf.base.vo.DownloadVO;
  14. import jnpf.base.vo.ListVO;
  15. import jnpf.base.vo.PageListVO;
  16. import jnpf.base.vo.PaginationVO;
  17. import jnpf.constant.FileTypeConstant;
  18. import jnpf.constant.MsgCode;
  19. import jnpf.constant.PermissionConst;
  20. import jnpf.exception.DataException;
  21. import jnpf.model.ExcelColumnAttr;
  22. import jnpf.model.ExcelImportForm;
  23. import jnpf.model.ExcelImportVO;
  24. import jnpf.model.ExcelModel;
  25. import jnpf.permission.constant.PosColumnMap;
  26. import jnpf.permission.entity.OrganizeEntity;
  27. import jnpf.permission.entity.PositionEntity;
  28. import jnpf.permission.entity.UserEntity;
  29. import jnpf.permission.entity.UserRelationEntity;
  30. import jnpf.permission.model.check.CheckResult;
  31. import jnpf.permission.model.permission.PermissionModel;
  32. import jnpf.permission.model.position.*;
  33. import jnpf.permission.model.user.mod.UserIdModel;
  34. import jnpf.permission.service.OrganizeService;
  35. import jnpf.permission.service.PositionService;
  36. import jnpf.permission.service.UserRelationService;
  37. import jnpf.permission.service.UserService;
  38. import jnpf.util.*;
  39. import jnpf.util.treeutil.SumTree;
  40. import jnpf.util.treeutil.newtreeutil.TreeDotUtils;
  41. import jnpf.workflow.service.TaskApi;
  42. import org.springframework.beans.factory.annotation.Autowired;
  43. import org.springframework.web.bind.annotation.*;
  44. import java.io.IOException;
  45. import java.util.*;
  46. import java.util.stream.Collectors;
  47. /**
  48. * 岗位信息
  49. *
  50. * @author JNPF开发平台组
  51. * @version V3.1.0
  52. * @copyright 引迈信息技术有限公司
  53. * @date 2019年9月26日 上午9:18
  54. */
  55. @Tag(name = "岗位管理", description = "Position")
  56. @RestController
  57. @RequestMapping("/api/permission/Position")
  58. public class PositionController extends SuperController<PositionService, PositionEntity> {
  59. @Autowired
  60. private UserService userService;
  61. @Autowired
  62. private PositionService positionService;
  63. @Autowired
  64. private OrganizeService organizeService;
  65. @Autowired
  66. private SysconfigService sysconfigApi;
  67. @Autowired
  68. private UserRelationService userRelationService;
  69. @Autowired
  70. private TaskApi taskApi;
  71. @Operation(summary = "获取岗位列表")
  72. @GetMapping
  73. public ActionResult<PageListVO<PositionListVO>> list(PositionPagination pagination) {
  74. pagination.setDataType(1);
  75. if (StringUtil.isNotEmpty(pagination.getKeyword())) {
  76. pagination.setDataType(null);
  77. }
  78. List<PositionEntity> data = positionService.getList(pagination);
  79. List<PositionTreeModel> list = JsonUtil.getJsonToList(data, PositionTreeModel.class);
  80. String dutyPost = "" ;
  81. if (StringUtil.isNotEmpty(pagination.getOrganizeId())) {
  82. OrganizeEntity org = organizeService.getInfo(pagination.getOrganizeId());
  83. dutyPost = org.getDutyPosition();
  84. }
  85. for (PositionTreeModel item : list) {
  86. if (StringUtil.isNotEmpty(dutyPost) && Objects.equals(dutyPost, item.getId())) {
  87. item.setIsDutyPosition(1);
  88. }
  89. //可设置责任岗位
  90. if (StringUtil.isEmpty(item.getParentId()) && !Objects.equals(item.getIsDutyPosition(), 1)) {
  91. item.setAllowDuty(1);
  92. }
  93. item.setIcon(PermissionConst.POSITION_ICON);
  94. }
  95. List<SumTree<PositionTreeModel>> trees = TreeDotUtils.convertListToTreeDot(list);
  96. List<PositionListVO> voList = JsonUtil.getJsonToList(trees, PositionListVO.class);
  97. PaginationVO paginationVO = JsonUtil.getJsonToBean(pagination, PaginationVO.class);
  98. return ActionResult.page(voList, paginationVO);
  99. }
  100. @Operation(summary = "新建岗位")
  101. @Parameters({
  102. @Parameter(name = "positionCrForm", description = "实体对象", required = true)
  103. })
  104. @SaCheckPermission("permission.organize")
  105. @PostMapping
  106. public ActionResult create(@RequestBody @Valid PositionCrForm positionCrForm) {
  107. PositionEntity entity = JsonUtil.getJsonToBean(positionCrForm, PositionEntity.class);
  108. if (positionService.isExistByFullName(entity, false)) {
  109. return ActionResult.fail(MsgCode.EXIST001.get());
  110. }
  111. if (positionService.isExistByEnCode(entity.getEnCode(), null)) {
  112. return ActionResult.fail(MsgCode.EXIST002.get());
  113. }
  114. if (!positionService.checkLevel(entity)) {
  115. return ActionResult.fail(MsgCode.PS038.get(sysconfigApi.getSysInfo().getPositionLevel()));
  116. }
  117. PosConModel posConModel = new PosConModel();
  118. //约束判断
  119. if (Objects.equals(entity.getIsCondition(), 1)) {
  120. posConModel = JsonUtil.getJsonToBean(entity.getConditionJson(), PosConModel.class);
  121. posConModel.init();
  122. String errStr = posConModel.checkCondition(entity.getId());
  123. if (StringUtil.isNotEmpty(errStr)) {
  124. return ActionResult.fail(errStr);
  125. }
  126. if (posConModel.getPrerequisiteFlag()) {
  127. for (String item : posConModel.getPrerequisite()) {
  128. PositionEntity itemInfo = positionService.getInfo(item);
  129. //先决只能1级(选中的先决岗位,这个岗位不能有先决条件,有的多就变成多级了)
  130. if (Objects.equals(itemInfo.getIsCondition(), 1)) {
  131. PosConModel itemModel = JsonUtil.getJsonToBean(itemInfo.getConditionJson(), PosConModel.class);
  132. itemModel.init();
  133. if (itemModel.getPrerequisiteFlag()) {
  134. return ActionResult.fail(MsgCode.SYS143.get());
  135. }
  136. }
  137. }
  138. }
  139. }
  140. positionService.create(entity);
  141. positionService.linkUpdate(entity.getId(), posConModel);
  142. return ActionResult.success(MsgCode.SU001.get());
  143. }
  144. @Operation(summary = "修改岗位")
  145. @Parameters({
  146. @Parameter(name = "id", description = "主键值", required = true),
  147. @Parameter(name = "positionUpForm", description = "实体对象", required = true)
  148. })
  149. @SaCheckPermission("permission.organize")
  150. @PutMapping("/{id}")
  151. public ActionResult update(@PathVariable("id") String id, @RequestBody @Valid PositionUpForm positionUpForm) {
  152. PositionEntity info = positionService.getInfo(id);
  153. PositionEntity entity = JsonUtil.getJsonToBean(positionUpForm, PositionEntity.class);
  154. entity.setId(id);
  155. if (info == null) {
  156. return ActionResult.fail(MsgCode.FA002.get());
  157. }
  158. PositionEntity parentInfo = positionService.getInfo(entity.getParentId());
  159. //不能放到自己下级内
  160. if (id.equals(entity.getParentId()) || (parentInfo != null && parentInfo.getPositionIdTree() != null && parentInfo.getPositionIdTree().contains(id))) {
  161. return ActionResult.fail(MsgCode.SYS146.get(MsgCode.PS004.get()));
  162. }
  163. //todo 当岗位绑定用户不让其更改(新版岗位还有绑定角色)
  164. if (userRelationService.existByObj(PermissionConst.POSITION, id)) {
  165. if (!positionService.getInfo(id).getOrganizeId().equals(positionUpForm.getOrganizeId())) {
  166. return ActionResult.fail(MsgCode.FA023.get());
  167. }
  168. }
  169. //todo 验证流程是否逐级审批
  170. if (!Objects.equals(info.getOrganizeId(), positionUpForm.getOrganizeId()) || !Objects.equals(info.getParentId(), positionUpForm.getParentId())) {
  171. List<String> stepList = taskApi.getStepList();
  172. if (!Objects.equals(info.getOrganizeId(), positionUpForm.getOrganizeId())) {
  173. if (stepList.contains(positionUpForm.getOrganizeId())) {
  174. return ActionResult.fail(MsgCode.PS041.get());
  175. }
  176. } else {
  177. if (stepList.contains(id)) {
  178. return ActionResult.fail(MsgCode.PS041.get());
  179. }
  180. }
  181. }
  182. if (positionService.isExistByFullName(entity, true)) {
  183. return ActionResult.fail(MsgCode.EXIST001.get());
  184. }
  185. if (positionService.isExistByEnCode(entity.getEnCode(), id)) {
  186. return ActionResult.fail(MsgCode.EXIST002.get());
  187. }
  188. if (!positionService.checkLevel(entity)) {
  189. return ActionResult.fail(MsgCode.PS038.get(sysconfigApi.getSysInfo().getPositionLevel()));
  190. }
  191. //约束判断
  192. PosConModel posConModel = new PosConModel();
  193. if (Objects.equals(entity.getIsCondition(), 1)) {
  194. posConModel = JsonUtil.getJsonToBean(entity.getConditionJson(), PosConModel.class);
  195. posConModel.init();
  196. String errStr = posConModel.checkCondition(entity.getId());
  197. if (StringUtil.isNotEmpty(errStr)) {
  198. return ActionResult.fail(errStr);
  199. }
  200. //修改岗位的时候,岗位有人的话,互斥岗位(选择的岗位下的人一个都不能重叠),先决岗位(选择的岗位下的人必须包含当前岗位人员)
  201. Set<String> userIds = userRelationService.getListByObjectId(entity.getId(), PermissionConst.POSITION)
  202. .stream().map(UserRelationEntity::getUserId).collect(Collectors.toSet());
  203. if (posConModel.getMutualExclusionFlag()) {
  204. for (String item : posConModel.getMutualExclusion()) {
  205. Set<String> itemUserIds = userRelationService.getListByObjectId(item, PermissionConst.POSITION)
  206. .stream().map(UserRelationEntity::getUserId).collect(Collectors.toSet());
  207. Set<String> commonIds = new HashSet<>(userIds);
  208. commonIds.retainAll(itemUserIds);
  209. //用户冲突,互斥修改失败
  210. if (!commonIds.isEmpty()) {
  211. return ActionResult.fail(MsgCode.SYS137.get());
  212. }
  213. }
  214. }
  215. if (posConModel.getPrerequisiteFlag()) {
  216. //获取全部岗位的先决岗位列表。用于判断当前岗位是否开启先决(存在就不能开启)
  217. List<PositionEntity> list = positionService.getList(false);
  218. Set<String> allPrePos = new HashSet<>();
  219. for (PositionEntity t : list) {
  220. if (Objects.equals(t.getIsCondition(), 1)) {
  221. PosConModel tm = JsonUtil.getJsonToBean(t.getConditionJson(), PosConModel.class);
  222. tm.init();
  223. if (tm.getPrerequisiteFlag()) {
  224. allPrePos.addAll(tm.getPrerequisite());
  225. }
  226. }
  227. }
  228. if (allPrePos.contains(id)) {
  229. return ActionResult.fail(MsgCode.SYS143.get());
  230. }
  231. //用户冲突--当前岗位里有用户就要判断先决包含先决的所有岗位
  232. if (CollectionUtil.isNotEmpty(userIds)) {
  233. for (String userId : userIds) {
  234. Set<String> posIds = userRelationService.getListByUserId(userId, PermissionConst.POSITION)
  235. .stream().map(UserRelationEntity::getObjectId).collect(Collectors.toSet());
  236. //用户冲突,先决修改失败
  237. if (!posIds.containsAll(posConModel.getPrerequisite())) {
  238. return ActionResult.fail(MsgCode.SYS138.get());
  239. }
  240. }
  241. }
  242. //先决只能1级(选中的先决岗位,这个岗位不能有先决条件,有的多就变成多级了)
  243. for (String item : posConModel.getPrerequisite()) {
  244. PositionEntity itemInfo = positionService.getInfo(item);
  245. if (Objects.equals(itemInfo.getIsCondition(), 1)) {
  246. PosConModel itemModel = JsonUtil.getJsonToBean(itemInfo.getConditionJson(), PosConModel.class);
  247. itemModel.init();
  248. if (itemModel.getPrerequisiteFlag()) {
  249. return ActionResult.fail(MsgCode.SYS143.get());
  250. }
  251. }
  252. }
  253. }
  254. }
  255. boolean flag = positionService.update(id, entity);
  256. if (flag == false) {
  257. return ActionResult.fail(MsgCode.FA002.get());
  258. }
  259. positionService.linkUpdate(id, posConModel);
  260. // 得到所有子组织或部门id
  261. if (!Objects.equals(info.getParentId(), entity.getParentId())) {
  262. List<PositionEntity> allChild = positionService.getAllChild(id);
  263. allChild.forEach(t -> {
  264. if (!t.getId().equals(id)) {
  265. String[] split = t.getPositionIdTree().split(id);
  266. t.setPositionIdTree(entity.getPositionIdTree() + split[1]);
  267. t.setOrganizeId(entity.getOrganizeId());
  268. positionService.update(t.getId(), t);
  269. }
  270. });
  271. }
  272. return ActionResult.success(MsgCode.SU004.get());
  273. }
  274. @Operation(summary = "获取岗位信息")
  275. @Parameters({
  276. @Parameter(name = "id", description = "主键值", required = true)
  277. })
  278. @SaCheckPermission("permission.organize")
  279. @GetMapping("/{id}")
  280. public ActionResult<PositionInfoVO> getInfo(@PathVariable("id") String id) throws DataException {
  281. PositionEntity entity = positionService.getInfo(id);
  282. PositionInfoVO vo = JsonUtilEx.getJsonToBeanEx(entity, PositionInfoVO.class);
  283. Map<String, Object> orgMap = organizeService.getOrgMap();
  284. List<PositionEntity> list = positionService.getList(false);
  285. Set<String> allPrePos = new HashSet<>();
  286. for (PositionEntity t : list) {
  287. if (Objects.equals(t.getIsCondition(), 1)) {
  288. PosConModel tm = JsonUtil.getJsonToBean(t.getConditionJson(), PosConModel.class);
  289. tm.init();
  290. if (tm.getPrerequisiteFlag()) {
  291. allPrePos.addAll(tm.getPrerequisite());
  292. }
  293. }
  294. }
  295. if (allPrePos.contains(id)) {
  296. vo.setIsPrePosition(true);
  297. }
  298. if (orgMap.containsKey(vo.getOrganizeId())) {
  299. vo.setOrganizeName(orgMap.get(vo.getOrganizeId()).toString());
  300. }
  301. return ActionResult.success(vo);
  302. }
  303. @Operation(summary = "删除岗位")
  304. @Parameters({
  305. @Parameter(name = "id", description = "主键值", required = true)
  306. })
  307. @SaCheckPermission("permission.organize")
  308. @DeleteMapping("/{id}")
  309. public ActionResult delete(@PathVariable("id") String id) {
  310. PositionEntity entity = positionService.getInfo(id);
  311. if (entity == null) {
  312. return ActionResult.fail(MsgCode.FA003.get());
  313. }
  314. //删除子孙岗位
  315. List<PositionEntity> allChild = positionService.getAllChild(id);
  316. //岗位下有用户不能删除,没有顺便删除岗位角色
  317. if (userRelationService.existByObj(PermissionConst.POSITION, allChild.stream().map(PositionEntity::getId).collect(Collectors.toList()))) {
  318. return ActionResult.fail(MsgCode.PS040.get(MsgCode.PS004.get()));
  319. }
  320. for (PositionEntity item : allChild) {
  321. positionService.delete(item);
  322. }
  323. return ActionResult.success(MsgCode.SU003.get());
  324. }
  325. //++++++++++++++++++++++++++++++++++++++++++动作start+++++++++++++++++++++++++
  326. @Operation(summary = "设为责任岗位")
  327. @Parameters({
  328. @Parameter(name = "id", description = "主键值", required = true),
  329. @Parameter(name = "organizeId", description = "组织id", required = true)
  330. })
  331. @SaCheckPermission("permission.organize")
  332. @PostMapping("{id}/Actions/DutyPosition")
  333. public ActionResult<PositionInfoVO> setDutyPostion(@PathVariable("id") String id, @RequestParam("organizeId") String organizeId) {
  334. OrganizeEntity org = organizeService.getInfo(organizeId);
  335. PositionEntity position = positionService.getInfo(id);
  336. if (org == null || position == null) {
  337. return ActionResult.fail(MsgCode.FA007.get());
  338. }
  339. org.setDutyPosition(id);
  340. organizeService.updateById(org);
  341. return ActionResult.success(MsgCode.SU005.get());
  342. }
  343. @Operation(summary = "设为责任人")
  344. @Parameters({
  345. @Parameter(name = "id", description = "主键值", required = true),
  346. @Parameter(name = "userId", description = "用户id", required = true)
  347. })
  348. @SaCheckPermission("permission.organize")
  349. @PostMapping("{id}/Actions/DutyUser")
  350. public ActionResult<PositionInfoVO> setDutyUser(@PathVariable("id") String id, @RequestParam("userId") String userId) {
  351. UserEntity user = userService.getInfo(userId);
  352. PositionEntity position = positionService.getInfo(id);
  353. if (user == null || position == null) {
  354. return ActionResult.fail(MsgCode.FA007.get());
  355. }
  356. position.setDutyUser(userId);
  357. positionService.updateById(position);
  358. return ActionResult.success(MsgCode.SU005.get());
  359. }
  360. //+++++++++++++++++动作end+++++++++++++控件接口start+++++++++++++++++++++++++++++++
  361. @Operation(summary = "岗位组件搜索")
  362. @GetMapping("/Selector")
  363. public ActionResult<PageListVO<PositionListVO>> selector(PositionPagination pagination) {
  364. pagination.setDataType(1);
  365. if (StringUtil.isNotEmpty(pagination.getKeyword())) {
  366. pagination.setDataType(null);
  367. }
  368. List<PositionEntity> data = positionService.getList(pagination);
  369. Map<String, Object> allOrgsTreeName = organizeService.getAllOrgsTreeName();
  370. List<PositionListVO> list = JsonUtil.getJsonToList(data, PositionListVO.class);
  371. for (PositionListVO item : list) {
  372. item.setIcon(PermissionConst.POSITION_ICON);
  373. item.setOrgNameTree(allOrgsTreeName.get(item.getOrganizeId()) + "/" + item.getFullName());
  374. if (StringUtil.isNotEmpty(pagination.getKeyword())) {
  375. item.setFullName(item.getOrgNameTree());
  376. }
  377. }
  378. PaginationVO paginationVO = JsonUtil.getJsonToBean(pagination, PaginationVO.class);
  379. return ActionResult.page(list, paginationVO);
  380. }
  381. @Operation(summary = "岗位组件树形")
  382. @GetMapping("/SelectorTree")
  383. public ActionResult<PageListVO<PositionListVO>> SelectorTree(PositionPagination pagination) {
  384. pagination.setDataType(1);
  385. List<PositionEntity> data = positionService.getList(pagination);
  386. Map<String, Object> allOrgsTreeName = organizeService.getAllOrgsTreeName();
  387. List<PositionTreeModel> list = JsonUtil.getJsonToList(data, PositionTreeModel.class);
  388. for (PositionTreeModel item : list) {
  389. item.setIcon(PermissionConst.POSITION_ICON);
  390. item.setOrgNameTree(allOrgsTreeName.get(item.getOrganizeId()) + "/" + item.getFullName());
  391. }
  392. List<SumTree<PositionTreeModel>> trees = TreeDotUtils.convertListToTreeDot(list);
  393. List<PositionListVO> listVO = JsonUtil.getJsonToList(trees, PositionListVO.class);
  394. return ActionResult.page(listVO, null);
  395. }
  396. @Operation(summary = "自定义范围回显")
  397. @Parameters({
  398. @Parameter(name = "userIdModel", description = "id", required = true)
  399. })
  400. @PostMapping("/SelectedList")
  401. public ActionResult<ListVO<PositionListVO>> SelectedList(@RequestBody UserIdModel userIdModel) {
  402. List<PositionListVO> list = positionService.selectedList(userIdModel.getIds());
  403. ListVO<PositionListVO> listVO = new ListVO<>();
  404. listVO.setList(list);
  405. return ActionResult.success(listVO);
  406. }
  407. @Operation(summary = "自定义范围下拉")
  408. @Parameters({
  409. @Parameter(name = "positionConditionModel", description = "岗位选择模型", required = true)
  410. })
  411. @PostMapping("/PositionCondition")
  412. public ActionResult<ListVO<PositionListVO>> positionCondition(@RequestBody UserIdModel userIdModel) {
  413. List<PositionEntity> list = positionService.positionCondition(userIdModel.getIds());
  414. Map<String, Object> allOrgsTreeName = organizeService.getAllOrgsTreeName();
  415. List<PositionTreeModel> modelList = JsonUtil.getJsonToList(list, PositionTreeModel.class);
  416. for (PositionTreeModel item : modelList) {
  417. item.setIcon(PermissionConst.POSITION_ICON);
  418. item.setFullName(allOrgsTreeName.get(item.getOrganizeId()) + "/" + item.getFullName());
  419. item.setOrgNameTree(item.getFullName());
  420. }
  421. List<SumTree<PositionTreeModel>> trees = TreeDotUtils.convertListToTreeDot(modelList);
  422. List<PositionListVO> voList = JsonUtil.getJsonToList(trees, PositionListVO.class);
  423. ListVO<PositionListVO> listVO = new ListVO<>();
  424. listVO.setList(voList);
  425. return ActionResult.success(listVO);
  426. }
  427. //++++++++++++++++++++++++++++++++++++++++++控件接口end+++++++++++++++++++++++++++
  428. @Operation(summary = "列表")
  429. @GetMapping("/All")
  430. public ActionResult<ListVO<PositionListAllVO>> listAll() {
  431. List<PositionEntity> list = positionService.getList(true);
  432. List<PositionListAllVO> vos = JsonUtil.getJsonToList(list, PositionListAllVO.class);
  433. ListVO<PositionListAllVO> vo = new ListVO<>();
  434. vo.setList(vos);
  435. return ActionResult.success(vo);
  436. }
  437. @Operation(summary = "通过组织id获取岗位列表")
  438. @Parameters({
  439. @Parameter(name = "organizeId", description = "主键值", required = true)
  440. })
  441. @SaCheckPermission("permission.organize")
  442. @GetMapping("/getList/{organizeId}")
  443. public ActionResult<List<PositionVo>> getListByOrganizeId(@PathVariable("organizeId") String organizeId) {
  444. List<PositionEntity> list = positionService.getListByOrganizeId(Collections.singletonList(organizeId), false);
  445. List<PositionVo> jsonToList = JsonUtil.getJsonToList(list, PositionVo.class);
  446. return ActionResult.success(jsonToList);
  447. }
  448. @Operation(summary = "获取岗位列表通过组织id数组")
  449. @Parameters({
  450. @Parameter(name = "organizeIds", description = "组织id数组", required = true)
  451. })
  452. @SaCheckPermission("permission.organize")
  453. @PostMapping("/getListByOrgIds")
  454. public ActionResult<ListVO<PermissionModel>> getListByOrganizeIds(@RequestBody @Valid Map<String, List<String>> organizeIds) {
  455. List<PermissionModel> PositionModelAll = new LinkedList<>();
  456. if (organizeIds.get("organizeIds") != null) {
  457. List<String> ids = organizeIds.get("organizeIds");
  458. PositionModelAll = positionService.getListByOrganizeIds(ids, false, true);
  459. }
  460. ListVO vo = new ListVO();
  461. vo.setList(PositionModelAll);
  462. return ActionResult.success(vo);
  463. }
  464. @Operation(summary = "模板下载")
  465. @SaCheckPermission("permission.organize")
  466. @GetMapping("/TemplateDownload")
  467. public ActionResult<DownloadVO> TemplateDownload() {
  468. PosColumnMap columnMap = new PosColumnMap();
  469. String excelName = columnMap.getExcelName();
  470. Map<String, String> keyMap = columnMap.getColumnByType(0);
  471. List<ExcelColumnAttr> models = columnMap.getFieldsModel(false);
  472. List<Map<String, Object>> list = columnMap.getDefaultList();
  473. Map<String, String[]> optionMap = getOptionMap();
  474. ExcelModel excelModel = ExcelModel.builder().models(models).selectKey(new ArrayList<>(keyMap.keySet())).optionMap(optionMap).build();
  475. DownloadVO vo = ExcelTool.getImportTemplate(FileTypeConstant.TEMPORARY, excelName, keyMap, list, excelModel);
  476. return ActionResult.success(vo);
  477. }
  478. @Operation(summary = "上传导入Excel")
  479. @SaCheckPermission("permission.organize")
  480. @PostMapping("/Uploader")
  481. public ActionResult<Object> Uploader() {
  482. return ExcelTool.uploader();
  483. }
  484. @Operation(summary = "导入预览")
  485. @SaCheckPermission("permission.organize")
  486. @GetMapping("/ImportPreview")
  487. public ActionResult<Map<String, Object>> ImportPreview(String fileName) throws Exception {
  488. // 导入字段
  489. PosColumnMap columnMap = new PosColumnMap();
  490. Map<String, String> keyMap = columnMap.getColumnByType(0);
  491. Map<String, Object> headAndDataMap = ExcelTool.importPreview(FileTypeConstant.TEMPORARY, fileName, keyMap);
  492. return ActionResult.success(headAndDataMap);
  493. }
  494. @Operation(summary = "导出异常报告")
  495. @SaCheckPermission("permission.organize")
  496. @PostMapping("/ExportExceptionData")
  497. public ActionResult<DownloadVO> ExportExceptionData(@RequestBody ExcelImportForm visualImportModel) {
  498. List<Map<String, Object>> dataList = visualImportModel.getList();
  499. PosColumnMap columnMap = new PosColumnMap();
  500. String excelName = columnMap.getExcelName();
  501. Map<String, String> keyMap = columnMap.getColumnByType(0);
  502. List<ExcelColumnAttr> models = columnMap.getFieldsModel(true);
  503. ExcelModel excelModel = ExcelModel.builder().optionMap(getOptionMap()).models(models).build();
  504. DownloadVO vo = ExcelTool.exportExceptionReport(FileTypeConstant.TEMPORARY, excelName, keyMap, dataList, excelModel);
  505. return ActionResult.success(vo);
  506. }
  507. @Operation(summary = "导入数据")
  508. @SaCheckPermission("permission.organize")
  509. @PostMapping("/ImportData")
  510. public ActionResult<ExcelImportVO> ImportData(@RequestBody ExcelImportForm visualImportModel) throws Exception {
  511. List<Map<String, Object>> listData = new ArrayList<>();
  512. List<Map<String, Object>> headerRow = new ArrayList<>();
  513. if (visualImportModel.isType()) {
  514. ActionResult result = ImportPreview(visualImportModel.getFileName());
  515. if (result == null) {
  516. throw new Exception(MsgCode.FA018.get());
  517. }
  518. if (result.getCode() != 200) {
  519. throw new Exception(result.getMsg());
  520. }
  521. if (result.getData() instanceof Map) {
  522. Map<String, Object> data = (Map<String, Object>) result.getData();
  523. listData = (List<Map<String, Object>>) data.get("dataRow");
  524. headerRow = (List<Map<String, Object>>) data.get("headerRow");
  525. }
  526. } else {
  527. listData = visualImportModel.getList();
  528. }
  529. List<PositionEntity> addList = new ArrayList<PositionEntity>();
  530. List<Map<String, Object>> failList = new ArrayList<>();
  531. // 对数据做校验
  532. this.validateImportData(listData, addList, failList);
  533. //正常数据插入
  534. for (PositionEntity each : addList) {
  535. positionService.create(each);
  536. }
  537. ExcelImportVO importModel = new ExcelImportVO();
  538. importModel.setSnum(addList.size());
  539. importModel.setFnum(failList.size());
  540. importModel.setResultType(failList.size() > 0 ? 1 : 0);
  541. importModel.setFailResult(failList);
  542. importModel.setHeaderRow(headerRow);
  543. return ActionResult.success(importModel);
  544. }
  545. @Operation(summary = "导出Excel")
  546. @SaCheckPermission("permission.organize")
  547. @GetMapping("/ExportData")
  548. public ActionResult ExportData(PositionPagination pagination) throws IOException {
  549. pagination.setDefaultMark(0);
  550. pagination.setDataType(1);
  551. List<PositionEntity> dataList = positionService.getList(pagination);
  552. //组织部门
  553. Map<String, String> orgMap = organizeService.getList(false)
  554. .stream().collect(Collectors.toMap(OrganizeEntity::getId, t -> t.getFullName() + "/" + t.getEnCode()));
  555. Map<String, String> posMap = positionService.getList(false)
  556. .stream().collect(Collectors.toMap(PositionEntity::getId, t -> t.getFullName() + "/" + t.getEnCode()));
  557. List<Map<String, Object>> realList = new ArrayList<>();
  558. for (PositionEntity entity : dataList) {
  559. Map<String, Object> positionMap = JsonUtil.entityToMap(entity);
  560. //组织
  561. String orgName = "" ;
  562. if (orgMap.containsKey(entity.getOrganizeId())) {
  563. orgName = orgMap.get(entity.getOrganizeId());
  564. }
  565. String parentName = "" ;
  566. if (posMap.containsKey(entity.getParentId())) {
  567. parentName = posMap.get(entity.getParentId());
  568. }
  569. positionMap.put("organizeId", orgName);
  570. positionMap.put("parentId", parentName);
  571. positionMap.put("isCondition", Objects.equals(entity.getIsCondition(), 1) ? "开" : "关");
  572. if (Objects.equals(entity.getIsCondition(), 1)) {
  573. PosConModel posConModel = JsonUtil.getJsonToBean(entity.getConditionJson(), PosConModel.class);
  574. posConModel.init();
  575. StringJoiner sj = new StringJoiner(",");
  576. if (posConModel.getMutualExclusionFlag()) {
  577. sj.add(PosColumnMap.constraintType.get(0));
  578. StringJoiner me = new StringJoiner(",");
  579. if (CollectionUtil.isNotEmpty(posConModel.getMutualExclusion())) {
  580. for (String s : posConModel.getMutualExclusion()) {
  581. if (posMap.get(s) != null) {
  582. me.add(posMap.get(s));
  583. }
  584. }
  585. }
  586. positionMap.put("mutualExclusion", me.toString());
  587. }
  588. if (posConModel.getNumFlag()) {
  589. sj.add(PosColumnMap.constraintType.get(1));
  590. positionMap.put("userNum", posConModel.getUserNum());
  591. positionMap.put("permissionNum", posConModel.getPermissionNum());
  592. }
  593. if (posConModel.getPrerequisiteFlag()) {
  594. sj.add(PosColumnMap.constraintType.get(2));
  595. StringJoiner me = new StringJoiner(",");
  596. if (CollectionUtil.isNotEmpty(posConModel.getMutualExclusion())) {
  597. for (String s : posConModel.getPrerequisite()) {
  598. if (posMap.get(s) != null) {
  599. me.add(posMap.get(s));
  600. }
  601. }
  602. }
  603. positionMap.put("prerequisite", me.toString());
  604. }
  605. positionMap.put("constraintType", sj.toString());
  606. }
  607. realList.add(positionMap);
  608. }
  609. PosColumnMap posColumnMap = new PosColumnMap();
  610. String excelName = posColumnMap.getExcelName();
  611. List<ExcelColumnAttr> models = posColumnMap.getFieldsModel(false);
  612. Map<String, String> keyMap = posColumnMap.getColumnByType(null);
  613. String[] keys = keyMap.keySet().toArray(new String[0]);
  614. ExcelModel excelModel = ExcelModel.builder().selectKey(Arrays.asList(keys)).models(models).optionMap(null).build();
  615. DownloadVO vo = ExcelTool.creatModelExcel(FileTypeConstant.TEMPORARY, excelName, keyMap, realList, excelModel);
  616. return ActionResult.success(vo);
  617. }
  618. private void validateImportData(List<Map<String, Object>> listData, List<PositionEntity> addList, List<Map<String, Object>> failList) {
  619. PosColumnMap columnMap = new PosColumnMap();
  620. Map<String, String> keyMap = columnMap.getColumnByType(0);
  621. List<PositionEntity> allPositionList = positionService.getList(false);
  622. Map<String, Object> nameCodeMap = organizeService.getOrgEncodeAndName(null);
  623. Integer posLevel = sysconfigApi.getSysInfo().getPositionLevel();
  624. //数据库所有部门map
  625. Map<String, String> allPosMap = allPositionList.stream().collect(Collectors.toMap(t -> t.getFullName() + "/" + t.getEnCode(), PositionEntity::getId));
  626. //新增成功的所有部门map
  627. Map<String, String> allAddPosMap = addList.stream().collect(Collectors.toMap(t -> t.getFullName() + "/" + t.getEnCode(), PositionEntity::getId));
  628. for (int i = 0, len = listData.size(); i < len; i++) {
  629. Map<String, Object> eachMap = listData.get(i);
  630. Map<String, Object> realMap = JsonUtil.getJsonToBean(eachMap, Map.class);
  631. StringJoiner errInfo = new StringJoiner(",");
  632. //所属组织判断,不存在后续不判断
  633. if (eachMap.get("organizeId") == null || StringUtil.isEmpty(eachMap.get("organizeId").toString())) {
  634. errInfo.add("所属组织不能为空");
  635. eachMap.put("errorsInfo", errInfo.toString());
  636. failList.add(eachMap);
  637. continue;
  638. }
  639. String organizeNameCode = eachMap.get("organizeId").toString();
  640. if (!nameCodeMap.containsKey(organizeNameCode)) {
  641. errInfo.add("找不到所属组织");
  642. eachMap.put("errorsInfo", errInfo.toString());
  643. failList.add(eachMap);
  644. continue;
  645. }
  646. String organizeId = nameCodeMap.get(organizeNameCode).toString();
  647. realMap.put("organizeId", organizeId);
  648. String parentPosTree = "" ;
  649. boolean isCondition = false;
  650. boolean hasExclusion = false;
  651. boolean hasNum = false;
  652. boolean hasPrerequisite = false;
  653. List<String> extList = new ArrayList<>();
  654. for (String column : keyMap.keySet()) {
  655. Object valueObj = eachMap.get(column);
  656. String value = valueObj == null ? null : String.valueOf(valueObj);
  657. String columnName = keyMap.get(column);
  658. switch (column) {
  659. case "parentId":
  660. if (StringUtil.isEmpty(value)) {
  661. break;
  662. }
  663. String pPosId = "" ;
  664. //数据库找父级
  665. PositionEntity pPost = allPositionList.stream().filter(t -> t.getOrganizeId().equals(organizeId)
  666. && (t.getFullName() + "/" + t.getEnCode()).equals(value)).findFirst().orElse(null);
  667. if (pPost == null) {
  668. //excel中找到父级
  669. pPost = addList.stream().filter(t -> t.getOrganizeId().equals(organizeId) && StringUtil.isNotEmpty(t.getEnCode())
  670. && (t.getFullName() + "/" + t.getEnCode()).equals(value)).findFirst().orElse(null);
  671. }
  672. if (pPost == null) {
  673. errInfo.add(columnName + "不存在");
  674. break;
  675. }
  676. pPosId = pPost.getId();
  677. parentPosTree = pPost.getPositionIdTree();
  678. //层级限制
  679. if (parentPosTree.split(",").length >= posLevel) {
  680. errInfo.add(MsgCode.PS038.get(posLevel));
  681. break;
  682. }
  683. realMap.put("parentId", pPosId);
  684. break;
  685. case "fullName":
  686. if (StringUtil.isEmpty(value)) {
  687. errInfo.add(columnName + "不能为空");
  688. break;
  689. }
  690. if (value.length() > 50) {
  691. errInfo.add(columnName + "值超出最多输入字符限制");
  692. }
  693. //值不能含有特殊符号
  694. if (!RegexUtils.checkSpecoalSymbols(value)) {
  695. errInfo.add(columnName + "值不能含有特殊符号");
  696. }
  697. String thisOrganizeId = organizeId;
  698. //库里重复
  699. long fullNameCount = allPositionList.stream().filter(t -> t.getOrganizeId().equals(thisOrganizeId) && t.getFullName().equals(value)).count();
  700. if (fullNameCount > 0) {
  701. errInfo.add(columnName + "值已存在");
  702. break;
  703. }
  704. //表格内重复
  705. fullNameCount = addList.stream().filter(t -> t.getOrganizeId().equals(thisOrganizeId) && t.getFullName().equals(value)).count();
  706. if (fullNameCount > 0) {
  707. errInfo.add(columnName + "值已存在");
  708. break;
  709. }
  710. break;
  711. case "enCode":
  712. if (StringUtil.isNotEmpty(value)) {
  713. if (value.length() > 50) {
  714. errInfo.add(columnName + "值超出最多输入字符限制");
  715. }
  716. if (!RegexUtils.checkEnCode(value)) {
  717. errInfo.add(columnName + "只能输入英文、数字和小数点且小数点不能放在首尾");
  718. }
  719. //库里重复
  720. long enCodeCount = allPositionList.stream().filter(t -> t.getEnCode().equals(value)).count();
  721. if (enCodeCount > 0) {
  722. errInfo.add(columnName + "值已存在");
  723. break;
  724. }
  725. //表格内重复
  726. enCodeCount = addList.stream().filter(t -> t.getEnCode().equals(value)).count();
  727. if (enCodeCount > 0) {
  728. errInfo.add(columnName + "值已存在");
  729. break;
  730. }
  731. }
  732. break;
  733. case "isCondition":
  734. //岗位约束开关
  735. if (StringUtil.isEmpty(value)) {
  736. realMap.put(column, 0);
  737. break;
  738. }
  739. if ("开".equals(value.toString())) {
  740. isCondition = true;
  741. }
  742. realMap.put(column, isCondition ? 1 : 0);
  743. break;
  744. case "constraintType":
  745. //岗位约束类型
  746. if (isCondition) {
  747. if (StringUtil.isEmpty(value)) {
  748. errInfo.add(columnName + "不能为空");
  749. break;
  750. }
  751. List<String> split = Arrays.asList(value.toString().split(","));
  752. Map<Integer, String> typeMap = PosColumnMap.constraintType;
  753. List<Integer> constraintTypeList = new ArrayList<>();
  754. for (Integer typeKey : typeMap.keySet()) {
  755. if (split.contains(typeMap.get(typeKey))) {
  756. if (Objects.equals(typeKey, 0)) {
  757. hasExclusion = true;
  758. }
  759. if (Objects.equals(typeKey, 1)) {
  760. hasNum = true;
  761. }
  762. if (Objects.equals(typeKey, 2)) {
  763. hasPrerequisite = true;
  764. }
  765. constraintTypeList.add(typeKey);
  766. }
  767. }
  768. if (CollectionUtil.isEmpty(constraintTypeList)) {
  769. errInfo.add(columnName + "值不正确");
  770. break;
  771. }
  772. realMap.put(column, constraintTypeList);
  773. }
  774. break;
  775. case "mutualExclusion":
  776. //岗位约束互斥
  777. if (hasExclusion) {
  778. if (StringUtil.isEmpty(value)) {
  779. errInfo.add(columnName + "不能为空");
  780. break;
  781. }
  782. List<String> exList = Arrays.asList(value.split(","));
  783. List<String> allExList = new ArrayList<>();
  784. for (String item : exList) {
  785. if (StringUtil.isNotEmpty(allPosMap.get(item))) {
  786. allExList.add(allPosMap.get(item));
  787. } else if (StringUtil.isNotEmpty(allAddPosMap.get(item))) {
  788. allExList.add(allAddPosMap.get(item));
  789. }
  790. }
  791. if (CollectionUtil.isEmpty(allExList) || exList.size() != allExList.size()) {
  792. errInfo.add(columnName + "值不正确");
  793. break;
  794. }
  795. extList = new ArrayList<>(allExList);
  796. realMap.put(column, allExList);
  797. } else {
  798. realMap.put(column, new ArrayList<>());
  799. }
  800. break;
  801. case "userNum":
  802. case "permissionNum":
  803. //岗位约束基数
  804. if (hasNum) {
  805. if (StringUtil.isEmpty(value)) {
  806. errInfo.add(columnName + "不能为空");
  807. break;
  808. }
  809. Integer userNum;
  810. try {
  811. userNum = Integer.parseInt(value);
  812. } catch (Exception e) {
  813. userNum = -1;
  814. }
  815. if (userNum <= 0) {
  816. errInfo.add(columnName + "值不正确");
  817. break;
  818. }
  819. realMap.put(column, userNum);
  820. } else {
  821. realMap.put(column, 1);
  822. }
  823. break;
  824. case "prerequisite":
  825. //岗位约束先决
  826. if (hasPrerequisite) {
  827. if (StringUtil.isEmpty(value)) {
  828. errInfo.add(columnName + "不能为空");
  829. break;
  830. }
  831. List<String> preList = Arrays.asList(value.split(","));
  832. List<String> allPreList = new ArrayList<>();
  833. for (String item : preList) {
  834. if (StringUtil.isNotEmpty(allPosMap.get(item))) {
  835. allPreList.add(allPosMap.get(item));
  836. } else if (StringUtil.isNotEmpty(allAddPosMap.get(item))) {
  837. allPreList.add(allAddPosMap.get(item));
  838. }
  839. }
  840. if (CollectionUtil.isEmpty(allPreList) || preList.size() != allPreList.size()) {
  841. errInfo.add(columnName + "值不正确");
  842. break;
  843. }
  844. //互斥,先决取交集
  845. extList.retainAll(allPreList);
  846. if (extList.size() > 0) {
  847. errInfo.add("互斥和先决对象不能是同一个对象");
  848. break;
  849. }
  850. for (String item : allPreList) {
  851. PositionEntity positionEntity = allPositionList.stream().filter(t -> t.getId().equals(item)).findFirst().orElse(null);
  852. if (positionEntity == null) {
  853. positionEntity = addList.stream().filter(t -> t.getId().equals(item)).findFirst().orElse(null);
  854. }
  855. if (Objects.equals(positionEntity.getIsCondition(), 1)) {
  856. PosConModel posConModel = JsonUtil.getJsonToBean(positionEntity.getConditionJson(), PosConModel.class);
  857. posConModel.init();
  858. if (posConModel.getPrerequisiteFlag()) {
  859. errInfo.add("先决约束冲突,先决限制1级");
  860. break;
  861. }
  862. }
  863. }
  864. realMap.put(column, allPreList);
  865. } else {
  866. realMap.put(column, new ArrayList<>());
  867. }
  868. break;
  869. case "sortCode":
  870. if (StringUtil.isEmpty(value)) {
  871. realMap.put("sortCode", 0);
  872. break;
  873. }
  874. Long numValue = 0l;
  875. try {
  876. numValue = Long.parseLong(value);
  877. } catch (Exception e) {
  878. errInfo.add(columnName + "值不正确");
  879. break;
  880. }
  881. if (numValue < 0) {
  882. errInfo.add(columnName + "值不能小于0");
  883. break;
  884. }
  885. if (numValue > 1000000) {
  886. errInfo.add(columnName + "值不能大于999999");
  887. break;
  888. }
  889. realMap.put(column, numValue);
  890. break;
  891. default:
  892. break;
  893. }
  894. }
  895. if (errInfo.length() == 0) {
  896. PositionEntity positionEntity = JsonUtil.getJsonToBean(realMap, PositionEntity.class);
  897. String id = RandomUtil.uuId();
  898. positionEntity.setId(id);
  899. positionEntity.setCreatorTime(new Date());
  900. positionEntity.setPositionIdTree(StringUtil.isNotEmpty(parentPosTree) ? parentPosTree + "," + id : id);
  901. if (isCondition) {
  902. PosConModel posConModel = JsonUtil.getJsonToBean(realMap, PosConModel.class);
  903. positionEntity.setConditionJson(JsonUtil.getObjectToString(posConModel));
  904. }
  905. addList.add(positionEntity);
  906. } else {
  907. eachMap.put("errorsInfo", errInfo.toString());
  908. failList.add(eachMap);
  909. }
  910. }
  911. }
  912. private CheckResult checkOrganizeId(String organizeName, Map<String, Object> allOrgsTreeName) {
  913. for (String key : allOrgsTreeName.keySet()) {
  914. Object o = allOrgsTreeName.get(key);
  915. if (organizeName.equals(o.toString())) {
  916. String[] split = key.split(",");
  917. return new CheckResult(true, null, split[split.length - 1]);
  918. }
  919. }
  920. return new CheckResult(false, "所属组织不正确", null);
  921. }
  922. /**
  923. * 获取下拉框
  924. *
  925. * @return
  926. */
  927. private Map<String, String[]> getOptionMap() {
  928. Map<String, String[]> optionMap = new HashMap<>();
  929. //约束开关
  930. optionMap.put("isCondition", new String[]{"开", "关"});
  931. return optionMap;
  932. }
  933. }