EmpUserCustomController.java 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855
  1. package com.jeesite.modules.mes.web;
  2. import com.jeesite.common.config.Global;
  3. import com.jeesite.common.collect.ListUtils;
  4. import com.jeesite.common.entity.Page;
  5. import com.jeesite.common.lang.DateUtils;
  6. import com.jeesite.common.lang.StringUtils;
  7. import com.jeesite.common.mybatis.mapper.query.QueryType;
  8. import com.jeesite.common.service.ServiceException;
  9. import com.jeesite.common.utils.excel.ExcelExport;
  10. import com.jeesite.common.utils.excel.ExcelImport;
  11. import com.jeesite.common.utils.excel.annotation.ExcelField.Type;
  12. import com.jeesite.common.web.BaseController;
  13. import com.jeesite.modules.mes.entity.excel.ExcelEmpUserEmployee;
  14. import com.jeesite.modules.mes.entity.MesEmployee;
  15. import com.jeesite.modules.mes.service.MesEmployeeService;
  16. import com.jeesite.modules.sys.entity.EmpUser;
  17. import com.jeesite.modules.sys.entity.*;
  18. import com.jeesite.modules.sys.service.EmployeeService;
  19. import com.jeesite.modules.sys.service.EmpUserService;
  20. import com.jeesite.modules.sys.service.UserService;
  21. import com.jeesite.modules.sys.utils.UserUtils;
  22. import com.jeesite.modules.sys.web.user.EmpUserController;
  23. import org.springframework.dao.EmptyResultDataAccessException;
  24. import org.springframework.beans.factory.annotation.Autowired;
  25. import org.springframework.jdbc.core.JdbcTemplate;
  26. import org.springframework.stereotype.Controller;
  27. import org.springframework.ui.Model;
  28. import org.springframework.web.bind.annotation.ModelAttribute;
  29. import org.springframework.web.bind.annotation.PostMapping;
  30. import org.springframework.web.bind.annotation.RequestMapping;
  31. import org.springframework.web.bind.annotation.ResponseBody;
  32. import org.springframework.web.multipart.MultipartFile;
  33. import javax.servlet.http.HttpServletRequest;
  34. import javax.servlet.http.HttpServletResponse;
  35. import java.util.ArrayList;
  36. import java.util.List;
  37. @Controller
  38. @RequestMapping(value = "${adminPath}/mes/empUserCustom")
  39. public class EmpUserCustomController extends BaseController {
  40. @Autowired
  41. private EmpUserController empUserController;
  42. @Autowired
  43. private EmpUserService empUserService;
  44. @Autowired
  45. private UserService userService;
  46. @Autowired
  47. private MesEmployeeService mesEmployeeService;
  48. @Autowired
  49. private EmployeeService employeeService;
  50. @Autowired
  51. private JdbcTemplate jdbcTemplate;
  52. @ModelAttribute
  53. public EmpUser get(String userCode, boolean isNewRecord) {
  54. return empUserService.get(userCode, isNewRecord);
  55. }
  56. @RequestMapping(value = "form")
  57. public String form(EmpUser empUser, String op, Model model) {
  58. if ("copy".equals(op)) {
  59. // 借用原生的 form 方法,获取全量数据(包括岗位、机构、角色)
  60. String view = empUserController.form(empUser, "edit", model);
  61. EmpUser fullUser = (EmpUser) model.asMap().get("empUser");
  62. if (fullUser != null) {
  63. // 将原记录转化为新记录
  64. fullUser.setIsNewRecord(true);
  65. fullUser.setUserCode(null);
  66. // 转换员工及附属机构的主键
  67. if (fullUser.getEmployee() != null) {
  68. fullUser.getEmployee().setIsNewRecord(true);
  69. fullUser.getEmployee().setEmpCode(null);
  70. List<EmployeeOffice> officeList = fullUser.getEmployee().getEmployeeOfficeList();
  71. if (officeList != null && !officeList.isEmpty()) {
  72. for (EmployeeOffice eo : officeList) {
  73. eo.setIsNewRecord(true);
  74. eo.setId(null);
  75. }
  76. }
  77. }
  78. // 处理角色回显
  79. List<Role> roleList = fullUser.getRoleList();
  80. if (roleList != null && !roleList.isEmpty()) {
  81. List<String> roleCodes = new ArrayList<>();
  82. for (Role role : roleList) {
  83. roleCodes.add(role.getRoleCode());
  84. }
  85. fullUser.setUserRoleString(StringUtils.join(roleCodes, ","));
  86. }
  87. // 覆盖 Model 中的对象并注入角色列表和操作标识
  88. model.addAttribute("empUser", fullUser);
  89. model.addAttribute("roleList", roleList);
  90. model.addAttribute("op", "add");
  91. }
  92. // 注入自定义保存脚本,修改表单 action 为我们自己的 save
  93. String customSaveScript = "<script>" +
  94. "$(function(){" +
  95. " var overrideAction = function() {" +
  96. " var form = $('#inputForm');" +
  97. " if(form.length > 0 && form.attr('action').indexOf('/mes/empUserCustom/save') === -1) {" +
  98. " form.attr('action', '" + Global.getAdminPath() + "/mes/empUserCustom/save');" +
  99. " }" +
  100. " };" +
  101. " overrideAction();" +
  102. " setInterval(overrideAction, 500);" +
  103. "});" +
  104. "</script>";
  105. model.addAttribute("customSaveScript", customSaveScript);
  106. // 为了防止 customSaveScript 没有被模板渲染,我们利用 extend 字段进行 XSS 注入(JeeSite 中扩展字段常用于透传)
  107. // 或者更安全的做法,只需 model 传参。这里保留之前的做法。
  108. return view;
  109. }
  110. String view = empUserController.form(empUser, op, model);
  111. applyEmployeePostName(model);
  112. return view;
  113. }
  114. @RequestMapping(value = "save")
  115. @ResponseBody
  116. public String save(EmpUser empUser, String oldLoginCode, HttpServletRequest request) {
  117. String loginCode = StringUtils.trim(empUser.getLoginCode());
  118. empUser.setLoginCode(loginCode);
  119. if (StringUtils.isBlank(loginCode)) {
  120. return renderResult(Global.FALSE, "保存用户失败,登录账号不能为空。");
  121. }
  122. if (loginCode.length() < 2) {
  123. return renderResult(Global.FALSE, "保存用户失败,登录账号至少输入 2 个字符。");
  124. }
  125. if (empUser.getEmployee() == null || StringUtils.isBlank(empUser.getEmployee().getEmpNo())) {
  126. return renderResult(Global.FALSE, "保存用户失败,员工工号不能为空。");
  127. }
  128. if (empUser.getEmployee() == null || StringUtils.isBlank(empUser.getEmployee().getEmpName())) {
  129. return renderResult(Global.FALSE, "保存用户失败,员工姓名不能为空。");
  130. }
  131. // 新增时若登录账号残留软删记录:先硬删残留,再按新增保存(不再做恢复)
  132. if (empUser.getIsNewRecord() || StringUtils.isBlank(empUser.getUserCode())) {
  133. User existByLogin = findUserByLoginCodeIncludeDeleted(loginCode);
  134. if (existByLogin != null) {
  135. if (User.STATUS_DELETE.equals(existByLogin.getStatus())) {
  136. phyDeleteUserByCode(existByLogin.getUserCode());
  137. } else if (!StringUtils.equals(existByLogin.getUserCode(), empUser.getUserCode())) {
  138. return renderResult(Global.FALSE, "保存用户失败,登录账号已存在,请修改登录账号!");
  139. }
  140. }
  141. }
  142. EmpUser existUser = new EmpUser();
  143. existUser.setLoginCode(loginCode);
  144. List<EmpUser> uList = empUserService.findList(existUser);
  145. if (hasOtherUser(uList, empUser.getUserCode())) {
  146. return renderResult(Global.FALSE, "保存用户失败,登录账号已存在(不能与原账号相同),请修改登录账号!");
  147. }
  148. if (StringUtils.isNotBlank(empUser.getUserName())) {
  149. EmpUser where = new EmpUser();
  150. where.setUserName(empUser.getUserName());
  151. List<EmpUser> list = empUserService.findList(where);
  152. if (hasOtherUser(list, empUser.getUserCode())) {
  153. return renderResult(Global.FALSE, "保存用户失败,用户昵称已存在(不能与原昵称相同),请修改用户昵称!");
  154. }
  155. }
  156. if (StringUtils.isBlank(empUser.getUserType())) {
  157. empUser.setUserType("employee");
  158. }
  159. MesEmployee selectedEmployee = findSelectedEmployee(empUser);
  160. String selectedEmployeeError = checkSelectedEmployee(empUser, selectedEmployee);
  161. if (StringUtils.isNotBlank(selectedEmployeeError)) {
  162. return renderResult(Global.FALSE, selectedEmployeeError);
  163. }
  164. if (selectedEmployee != null) {
  165. User boundUser = findBoundUser(selectedEmployee);
  166. if (boundUser != null
  167. && (StringUtils.isBlank(empUser.getUserCode())
  168. || !StringUtils.equals(boundUser.getUserCode(), empUser.getUserCode()))) {
  169. // 若绑定的是软删残留账号,硬删后允许重新开户
  170. if (User.STATUS_DELETE.equals(boundUser.getStatus())) {
  171. phyDeleteUserByCode(boundUser.getUserCode());
  172. } else {
  173. return renderResult(Global.FALSE, "保存用户失败,该员工已创建账号:" + boundUser.getLoginCode());
  174. }
  175. }
  176. bindSelectedEmployeeUser(empUser, selectedEmployee);
  177. userService.save(empUser);
  178. if (shouldSaveAuth(request)) {
  179. userService.saveAuth(empUser);
  180. }
  181. return renderResult(Global.TRUE, "保存用户 '" + empUser.getLoginCode() + "' 成功");
  182. }
  183. String result = empUserController.save(empUser, oldLoginCode, request);
  184. saveRolesOnEdit(empUser, request, result);
  185. return result;
  186. }
  187. /**
  188. * 删除用户:物理删除账号、授权,并同步硬删员工档案
  189. */
  190. @RequestMapping(value = "delete")
  191. @ResponseBody
  192. public String delete(EmpUser empUser) {
  193. if (empUser == null || StringUtils.isBlank(empUser.getUserCode())) {
  194. return renderResult(Global.FALSE, text("删除用户失败,用户编码不能为空!"));
  195. }
  196. EmpUser dbUser = empUserService.get(empUser.getUserCode());
  197. if (dbUser == null) {
  198. // 可能已被软删,按编码直接硬删残留
  199. phyDeleteUserAndEmployee(empUser.getUserCode(), null);
  200. return renderResult(Global.TRUE, text("删除用户成功"));
  201. }
  202. String loginCode = dbUser.getLoginCode();
  203. String empCode = StringUtils.defaultIfBlank(dbUser.getRefCode(),
  204. dbUser.getEmployee() != null ? dbUser.getEmployee().getEmpCode() : null);
  205. phyDeleteUserAndEmployee(dbUser.getUserCode(), empCode);
  206. UserUtils.clearCache(dbUser);
  207. return renderResult(Global.TRUE, text("删除用户''{0}''成功", loginCode));
  208. }
  209. /**
  210. * 登录账号远程校验
  211. */
  212. @RequestMapping(value = "checkLoginCode")
  213. @ResponseBody
  214. public String checkLoginCode(String oldLoginCode, String loginCode) {
  215. loginCode = StringUtils.trim(loginCode);
  216. if (StringUtils.isBlank(loginCode)) {
  217. return "true";
  218. }
  219. if (StringUtils.isNotBlank(oldLoginCode) && StringUtils.equals(oldLoginCode, loginCode)) {
  220. return "true";
  221. }
  222. User exists = findUserByLoginCodeIncludeDeleted(loginCode);
  223. if (exists == null) {
  224. return "true";
  225. }
  226. // 软删残留视为可用(保存时会硬删残留后新建)
  227. if (User.STATUS_DELETE.equals(exists.getStatus())) {
  228. return "true";
  229. }
  230. return "false";
  231. }
  232. @RequestMapping(value = "listData")
  233. @ResponseBody
  234. public Page<EmpUser> listData(EmpUser empUser, Boolean isAll, String ctrlPermi, String ctrlPermiFilter,
  235. HttpServletRequest request, HttpServletResponse response) {
  236. applyOfficeTreeFilter(empUser, Boolean.TRUE.equals(isAll));
  237. empUser.setPage(new Page<>(request, response));
  238. return empUserService.findPage(empUser);
  239. }
  240. private void applyOfficeTreeFilter(EmpUser empUser, boolean isAll) {
  241. if (isAll) {
  242. return;
  243. }
  244. User currentUser = UserUtils.getUser();
  245. if (currentUser == null || currentUser.isSuperAdmin()) {
  246. return;
  247. }
  248. if (empUser.getEmployee() != null && empUser.getEmployee().getCompany() != null) {
  249. empUser.getEmployee().getCompany().setIsQueryChildren(true);
  250. }
  251. Office office = empUser.getEmployee() == null ? null : empUser.getEmployee().getOffice();
  252. String officeCode = office == null ? null : office.getOfficeCode();
  253. if (office != null) {
  254. office.setIsQueryChildren(true);
  255. }
  256. if (StringUtils.isNotBlank(officeCode) && !isTopOffice(officeCode)) {
  257. List<String> officeCodes = findPermittedOfficeCodes(currentUser.getUserCode(), officeCode);
  258. if (officeCodes.isEmpty()) {
  259. officeCodes.add("__NO_AUTH_OFFICE__");
  260. }
  261. empUser.getSqlMap().getWhere().and("o.office_code", QueryType.IN, officeCodes.toArray(new String[0]));
  262. return;
  263. }
  264. List<String> officeCodes = findPermittedOfficeCodes(currentUser.getUserCode(), officeCode);
  265. if (officeCodes.isEmpty()) {
  266. officeCodes.add("__NO_AUTH_OFFICE__");
  267. }
  268. empUser.getSqlMap().getWhere().and("o.office_code", QueryType.IN, officeCodes.toArray(new String[0]));
  269. if (office != null) {
  270. office.setOfficeCode(null);
  271. }
  272. }
  273. private boolean isTopOffice(String officeCode) {
  274. try {
  275. String parentCode = jdbcTemplate.queryForObject(
  276. "select parent_code from js_sys_office where office_code = ?",
  277. String.class, officeCode);
  278. return StringUtils.isBlank(parentCode) || "0".equals(parentCode);
  279. } catch (EmptyResultDataAccessException ex) {
  280. return false;
  281. }
  282. }
  283. private List<String> findPermittedOfficeCodes(String userCode, String rootOfficeCode) {
  284. if (StringUtils.isBlank(userCode)) {
  285. return ListUtils.newArrayList();
  286. }
  287. boolean selectedTopOffice = StringUtils.isNotBlank(rootOfficeCode) && isTopOffice(rootOfficeCode);
  288. if (StringUtils.isBlank(rootOfficeCode) || selectedTopOffice) {
  289. List<String> officeCodes = queryPermittedOfficeCodes(userCode, rootOfficeCode, true);
  290. if (!officeCodes.isEmpty()) {
  291. return officeCodes;
  292. }
  293. } else if (!queryPermittedOfficeCodes(userCode, null, true).isEmpty()) {
  294. return queryPermittedOfficeCodes(userCode, rootOfficeCode, true);
  295. }
  296. return queryPermittedOfficeCodes(userCode, rootOfficeCode, false);
  297. }
  298. private List<String> queryPermittedOfficeCodes(String userCode, String rootOfficeCode, boolean onlySpecificScopes) {
  299. List<Object> params = ListUtils.newArrayList();
  300. StringBuilder sql = new StringBuilder();
  301. sql.append("select distinct o.office_code ");
  302. sql.append("from js_sys_office o ");
  303. sql.append("where 1 = 1 ");
  304. if (StringUtils.isNotBlank(rootOfficeCode)) {
  305. sql.append("and (o.office_code = ? or o.parent_codes like concat('%,', ?, ',%')) ");
  306. params.add(rootOfficeCode);
  307. params.add(rootOfficeCode);
  308. }
  309. sql.append("and exists (");
  310. sql.append(" select 1 from (");
  311. sql.append(" select rds.ctrl_data from js_sys_role_data_scope rds ");
  312. sql.append(" join js_sys_user_role ur on ur.role_code = rds.role_code ");
  313. sql.append(" where ur.user_code = ? and rds.ctrl_type = 'Office' and rds.ctrl_permi = '1' ");
  314. sql.append(" union ");
  315. sql.append(" select uds.ctrl_data from js_sys_user_data_scope uds ");
  316. sql.append(" where uds.user_code = ? and uds.ctrl_type = 'Office' and uds.ctrl_permi = '1' ");
  317. sql.append(" ) ds ");
  318. sql.append(" join js_sys_office so on so.office_code = ds.ctrl_data ");
  319. sql.append(" where (o.office_code = ds.ctrl_data or o.parent_codes like concat('%,', ds.ctrl_data, ',%')) ");
  320. params.add(userCode);
  321. params.add(userCode);
  322. if (onlySpecificScopes) {
  323. if (StringUtils.isBlank(rootOfficeCode)) {
  324. sql.append(" and so.parent_code is not null and so.parent_code <> '0' ");
  325. } else if (!isTopOffice(rootOfficeCode)) {
  326. sql.append(" and so.parent_code is not null and so.parent_code <> '0' ");
  327. } else {
  328. sql.append(" and ds.ctrl_data <> ? and so.parent_codes like concat('%,', ?, ',%') ");
  329. params.add(rootOfficeCode);
  330. params.add(rootOfficeCode);
  331. }
  332. } else if (StringUtils.isNotBlank(rootOfficeCode)) {
  333. sql.append(" and exists (");
  334. sql.append(" select 1 from js_sys_office selected ");
  335. sql.append(" where selected.office_code = ? ");
  336. sql.append(" and (so.office_code = selected.office_code ");
  337. sql.append(" or so.parent_codes like concat('%,', selected.office_code, ',%') ");
  338. sql.append(" or selected.parent_codes like concat('%,', so.office_code, ',%'))");
  339. sql.append(" ) ");
  340. params.add(rootOfficeCode);
  341. }
  342. sql.append(")");
  343. return jdbcTemplate.queryForList(sql.toString(), String.class, params.toArray());
  344. }
  345. private boolean shouldSaveAuth(HttpServletRequest request) {
  346. return "auth".equals(request.getParameter("op")) || request.getParameterMap().containsKey("userRoleString");
  347. }
  348. /**
  349. * 编辑用户时原生保存不会写角色,这里在保存成功后补写。
  350. */
  351. private void saveRolesOnEdit(EmpUser empUser, HttpServletRequest request, String result) {
  352. if (!"edit".equals(request.getParameter("op"))) {
  353. return;
  354. }
  355. if (!shouldSaveAuth(request) || !isSuccessResult(result)) {
  356. return;
  357. }
  358. if (UserUtils.getSubject() == null || !UserUtils.getSubject().isPermitted("sys:empUser:authRole")) {
  359. return;
  360. }
  361. userService.saveAuth(empUser);
  362. }
  363. private boolean isSuccessResult(String result) {
  364. if (StringUtils.isBlank(result)) {
  365. return false;
  366. }
  367. return StringUtils.contains(result, "\"result\":\"" + Global.TRUE + "\"")
  368. || StringUtils.contains(result, "'result':'" + Global.TRUE + "'");
  369. }
  370. @RequestMapping(value = "exportData")
  371. public void exportData(EmpUser empUser, String ctrlPermi, String ctrlPermiFilter, HttpServletResponse response) {
  372. applyOfficeTreeFilter(empUser, false);
  373. List<ExcelEmpUserEmployee> list = ListUtils.newArrayList();
  374. for (EmpUser user : empUserService.findList(empUser)) {
  375. list.add(toExcel(user));
  376. }
  377. String fileName = "\u7528\u6237\u5458\u5de5\u6570\u636e" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx";
  378. try (ExcelExport ee = new ExcelExport("\u7528\u6237\u5458\u5de5\u6570\u636e", ExcelEmpUserEmployee.class)) {
  379. ee.setDataList(list).write(response, fileName);
  380. }
  381. }
  382. @RequestMapping(value = "importTemplate")
  383. public void importTemplate(HttpServletResponse response) {
  384. List<ExcelEmpUserEmployee> list = ListUtils.newArrayList(new ExcelEmpUserEmployee());
  385. String fileName = "\u7528\u6237\u5458\u5de5\u6570\u636e\u6a21\u677f.xlsx";
  386. try (ExcelExport ee = new ExcelExport("\u7528\u6237\u5458\u5de5\u6570\u636e", ExcelEmpUserEmployee.class, Type.IMPORT)) {
  387. ee.setDataList(list).write(response, fileName);
  388. }
  389. }
  390. @PostMapping(value = "importData")
  391. @ResponseBody
  392. public String importData(MultipartFile file, String updateSupport) {
  393. try {
  394. String message = importUserEmployeeData(file, "1".equals(updateSupport));
  395. return renderResult(Global.TRUE, "posfull:" + message);
  396. } catch (Exception ex) {
  397. return renderResult(Global.FALSE, "posfull:" + ex.getMessage());
  398. }
  399. }
  400. private String importUserEmployeeData(MultipartFile file, boolean updateSupport) {
  401. if (file == null) {
  402. throw new ServiceException("\u8bf7\u9009\u62e9\u5bfc\u5165\u7684\u6570\u636e\u6587\u4ef6\uff01");
  403. }
  404. int successNum = 0;
  405. int failureNum = 0;
  406. StringBuilder successMsg = new StringBuilder();
  407. StringBuilder failureMsg = new StringBuilder();
  408. try (ExcelImport ei = new ExcelImport(file, 2, 0)) {
  409. List<ExcelEmpUserEmployee> list = ei.getDataList(ExcelEmpUserEmployee.class);
  410. for (ExcelEmpUserEmployee item : list) {
  411. try {
  412. EmpUser empUser = buildImportUser(item, updateSupport);
  413. userService.save(empUser);
  414. if (StringUtils.isNotBlank(item.getUserRoleString())) {
  415. userService.saveAuth(empUser);
  416. }
  417. successNum++;
  418. successMsg.append("<br/>").append(successNum).append("\u3001\u8d26\u53f7 ")
  419. .append(item.getLoginCode()).append(" \u5bfc\u5165\u6210\u529f");
  420. } catch (Exception e) {
  421. failureNum++;
  422. String msg = "<br/>" + failureNum + "\u3001\u8d26\u53f7 "
  423. + StringUtils.defaultString(item.getLoginCode(), item.getEmpName())
  424. + " \u5bfc\u5165\u5931\u8d25\uff1a" + e.getMessage();
  425. failureMsg.append(msg);
  426. logger.error(msg, e);
  427. }
  428. }
  429. } catch (Exception e) {
  430. logger.error(e.getMessage(), e);
  431. throw new ServiceException(e.getMessage());
  432. }
  433. if (failureNum > 0) {
  434. failureMsg.insert(0, "\u5f88\u62b1\u6b49\uff0c\u5bfc\u5165\u5931\u8d25\uff01\u5171 " + failureNum + " \u6761\u6570\u636e\u683c\u5f0f\u4e0d\u6b63\u786e\uff0c\u9519\u8bef\u5982\u4e0b\uff1a");
  435. throw new ServiceException(failureMsg.toString());
  436. }
  437. successMsg.insert(0, "\u606d\u559c\u60a8\uff0c\u6570\u636e\u5df2\u5168\u90e8\u5bfc\u5165\u6210\u529f\uff01\u5171 " + successNum + " \u6761\uff0c\u6570\u636e\u5982\u4e0b\uff1a");
  438. return successMsg.toString();
  439. }
  440. private EmpUser buildImportUser(ExcelEmpUserEmployee item, boolean updateSupport) {
  441. item.setLoginCode(StringUtils.trim(item.getLoginCode()));
  442. item.setEmpCode(StringUtils.trim(item.getEmpCode()));
  443. item.setEmpNo(StringUtils.trim(item.getEmpNo()));
  444. item.setEmpName(StringUtils.trim(item.getEmpName()));
  445. if (StringUtils.isBlank(item.getLoginCode())) {
  446. throw new ServiceException("\u767b\u5f55\u8d26\u53f7\u4e0d\u80fd\u4e3a\u7a7a");
  447. }
  448. if (StringUtils.isBlank(item.getEmpName())) {
  449. throw new ServiceException("\u5458\u5de5\u59d3\u540d\u4e0d\u80fd\u4e3a\u7a7a");
  450. }
  451. if (StringUtils.isBlank(item.getEmpNo())) {
  452. item.setEmpNo(item.getLoginCode());
  453. }
  454. MesEmployee employee = findOrCreateEmployee(item);
  455. User query = new User();
  456. query.setLoginCode(item.getLoginCode());
  457. User exists = userService.getByLoginCode(query);
  458. if (exists != null && !updateSupport) {
  459. throw new ServiceException("\u767b\u5f55\u8d26\u53f7\u5df2\u5b58\u5728");
  460. }
  461. if (exists != null && StringUtils.isNotBlank(exists.getRefCode())
  462. && !StringUtils.equals(exists.getRefCode(), employee.getEmpCode())) {
  463. User boundQuery = new User();
  464. boundQuery.setUserType("employee");
  465. boundQuery.setRefCode(employee.getEmpCode());
  466. User boundUser = userService.getByUserTypeAndRefCode(boundQuery);
  467. if (boundUser != null && !StringUtils.equals(boundUser.getUserCode(), exists.getUserCode())) {
  468. throw new ServiceException("\u5458\u5de5\u5df2\u5173\u8054\u5176\u4ed6\u8d26\u53f7\uff1a" + boundUser.getLoginCode());
  469. }
  470. }
  471. EmpUser empUser = new EmpUser(exists == null ? null : exists.getUserCode());
  472. if (exists != null) {
  473. empUser = empUserService.get(exists.getUserCode(), false);
  474. }
  475. empUser.setLoginCode(item.getLoginCode());
  476. empUser.setUserName(StringUtils.defaultIfBlank(item.getUserName(), item.getEmpName()));
  477. empUser.setEmail(item.getEmail());
  478. empUser.setMobile(item.getMobile());
  479. empUser.setPhone(item.getPhone());
  480. empUser.setStatus(StringUtils.defaultIfBlank(item.getStatus(), User.STATUS_NORMAL));
  481. empUser.setUserType("employee");
  482. empUser.setMgrType(StringUtils.defaultIfBlank(empUser.getMgrType(), "0"));
  483. empUser.setRefCode(employee.getEmpCode());
  484. empUser.setRefName(employee.getEmpName());
  485. empUser.setUserRoleString(item.getUserRoleString());
  486. empUser.setEmployee(null);
  487. return empUser;
  488. }
  489. private MesEmployee findOrCreateEmployee(ExcelEmpUserEmployee item) {
  490. MesEmployee employee = null;
  491. if (StringUtils.isNotBlank(item.getEmpCode())) {
  492. employee = mesEmployeeService.get(new MesEmployee(item.getEmpCode()));
  493. }
  494. if (employee == null && StringUtils.isNotBlank(item.getEmpNo())) {
  495. MesEmployee where = new MesEmployee();
  496. where.setEmpNo(item.getEmpNo());
  497. List<MesEmployee> list = mesEmployeeService.findList(where);
  498. if (list != null && !list.isEmpty()) {
  499. employee = list.get(0);
  500. }
  501. }
  502. if (employee == null) {
  503. employee = new MesEmployee();
  504. employee.setEmpCode(item.getEmpCode());
  505. }
  506. employee.setEmpName(item.getEmpName());
  507. employee.setEmpNameEn(item.getEmpNameEn());
  508. employee.setEmpNo(item.getEmpNo());
  509. employee.setOfficeCode(item.getOfficeCode());
  510. employee.setOfficeName(item.getOfficeName());
  511. employee.setCompanyCode(item.getCompanyCode());
  512. employee.setCompanyName(item.getCompanyName());
  513. employee.setPostCode(item.getPostCode());
  514. employee.setPostName(item.getPostName());
  515. employee.setRemarks(item.getRemarks());
  516. employee.setStatus(MesEmployee.STATUS_NORMAL);
  517. mesEmployeeService.save(employee);
  518. saveEmployeePostList(employee, item.getPostCode());
  519. syncUserEmployeePost(employee, item.getPostCode(), item.getPostName());
  520. return employee;
  521. }
  522. private void saveEmployeePostList(MesEmployee employee, String postCodes) {
  523. if (employee == null || StringUtils.isBlank(employee.getEmpCode()) || StringUtils.isBlank(postCodes)) {
  524. return;
  525. }
  526. Employee sysEmployee = employeeService.get(new Employee(employee.getEmpCode()));
  527. if (sysEmployee == null) {
  528. return;
  529. }
  530. sysEmployee.setPostCode(StringUtils.trim(postCodes));
  531. sysEmployee.setEmployeePostList(buildEmployeePostList(postCodes));
  532. sysEmployee.setIsNewRecord(false);
  533. employeeService.save(sysEmployee);
  534. }
  535. private void syncUserEmployeePost(MesEmployee employee, String postCode, String postName) {
  536. if (employee == null) {
  537. return;
  538. }
  539. User query = new User();
  540. query.setUserType("employee");
  541. query.setRefCode(employee.getEmpCode());
  542. User boundUser = userService.getByUserTypeAndRefCode(query);
  543. if (boundUser == null) {
  544. return;
  545. }
  546. Employee sysEmployee = employeeService.get(new Employee(boundUser.getUserCode()));
  547. if (sysEmployee == null) {
  548. return;
  549. }
  550. if (StringUtils.isNotBlank(postCode)) {
  551. sysEmployee.setPostCode(StringUtils.trim(postCode));
  552. }
  553. employeeService.save(sysEmployee);
  554. }
  555. private List<EmployeePost> buildEmployeePostList(String postCodes) {
  556. List<EmployeePost> employeePostList = ListUtils.newArrayList();
  557. for (String postCode : StringUtils.split(StringUtils.trim(postCodes), ",")) {
  558. if (StringUtils.isNotBlank(postCode)) {
  559. employeePostList.add(new EmployeePost(null, StringUtils.trim(postCode)));
  560. }
  561. }
  562. return employeePostList;
  563. }
  564. private ExcelEmpUserEmployee toExcel(EmpUser user) {
  565. ExcelEmpUserEmployee excel = new ExcelEmpUserEmployee();
  566. excel.setLoginCode(user.getLoginCode());
  567. excel.setUserName(user.getUserName());
  568. excel.setEmail(user.getEmail());
  569. excel.setMobile(user.getMobile());
  570. excel.setPhone(user.getPhone());
  571. excel.setStatus(user.getStatus());
  572. MesEmployee employee = null;
  573. if (StringUtils.isNotBlank(user.getRefCode())) {
  574. employee = mesEmployeeService.get(new MesEmployee(user.getRefCode()));
  575. }
  576. if (employee == null) {
  577. employee = new MesEmployee();
  578. if (user.getEmployee() != null) {
  579. employee.setEmpCode(user.getEmployee().getEmpCode());
  580. employee.setEmpNo(user.getEmployee().getEmpNo());
  581. employee.setEmpName(user.getEmployee().getEmpName());
  582. employee.setEmpNameEn(user.getEmployee().getEmpNameEn());
  583. if (user.getEmployee().getOffice() != null) {
  584. employee.setOfficeCode(user.getEmployee().getOffice().getOfficeCode());
  585. employee.setOfficeName(user.getEmployee().getOffice().getOfficeName());
  586. }
  587. if (user.getEmployee().getCompany() != null) {
  588. employee.setCompanyCode(user.getEmployee().getCompany().getCompanyCode());
  589. employee.setCompanyName(user.getEmployee().getCompany().getCompanyName());
  590. }
  591. employee.setPostCode(user.getEmployee().getPostCode());
  592. }
  593. }
  594. excel.setEmpCode(employee.getEmpCode());
  595. excel.setEmpNo(employee.getEmpNo());
  596. excel.setEmpName(StringUtils.defaultIfBlank(employee.getEmpName(), user.getRefName()));
  597. excel.setEmpNameEn(employee.getEmpNameEn());
  598. excel.setOfficeCode(employee.getOfficeCode());
  599. excel.setOfficeName(employee.getOfficeName());
  600. excel.setCompanyCode(employee.getCompanyCode());
  601. excel.setCompanyName(employee.getCompanyName());
  602. excel.setPostCode(employee.getPostCode());
  603. excel.setPostName(employee.getPostName());
  604. excel.setRemarks(employee.getRemarks());
  605. return excel;
  606. }
  607. private MesEmployee findSelectedEmployee(EmpUser empUser) {
  608. if (empUser.getEmployee() == null) {
  609. if (StringUtils.isNotBlank(empUser.getRefCode())) {
  610. return mesEmployeeService.get(new MesEmployee(StringUtils.trim(empUser.getRefCode())));
  611. }
  612. return null;
  613. }
  614. if (StringUtils.isNotBlank(empUser.getEmployee().getEmpCode())) {
  615. MesEmployee employee = mesEmployeeService.get(new MesEmployee(empUser.getEmployee().getEmpCode()));
  616. if (employee != null) {
  617. return employee;
  618. }
  619. }
  620. if (StringUtils.isNotBlank(empUser.getEmployee().getEmpNo())) {
  621. MesEmployee where = new MesEmployee();
  622. where.setEmpNo(StringUtils.trim(empUser.getEmployee().getEmpNo()));
  623. List<MesEmployee> employees = mesEmployeeService.findList(where);
  624. if (employees != null && !employees.isEmpty()) {
  625. return employees.get(0);
  626. }
  627. }
  628. return null;
  629. }
  630. private void applyEmployeePostName(Model model) {
  631. EmpUser empUser = (EmpUser) model.asMap().get("empUser");
  632. MesEmployee employee = findSelectedEmployee(empUser);
  633. if (employee == null) {
  634. return;
  635. }
  636. if (empUser != null) {
  637. if (empUser.getEmployee() == null) {
  638. empUser.setEmployee(new Employee(employee.getEmpCode()));
  639. }
  640. if (StringUtils.isBlank(empUser.getEmployee().getEmpCode())) {
  641. empUser.getEmployee().setEmpCode(employee.getEmpCode());
  642. }
  643. if (StringUtils.isBlank(empUser.getEmployee().getEmpNo())) {
  644. empUser.getEmployee().setEmpNo(employee.getEmpNo());
  645. }
  646. if (StringUtils.isBlank(empUser.getEmployee().getEmpName())) {
  647. empUser.getEmployee().setEmpName(employee.getEmpName());
  648. }
  649. if (StringUtils.isBlank(empUser.getEmployee().getEmpNameEn())) {
  650. empUser.getEmployee().setEmpNameEn(employee.getEmpNameEn());
  651. }
  652. if (StringUtils.isBlank(empUser.getEmployee().getPostCode())) {
  653. empUser.getEmployee().setPostCode(employee.getPostCode());
  654. }
  655. }
  656. model.addAttribute("employeePostName", employee.getPostName());
  657. model.addAttribute("empUser", empUser);
  658. }
  659. private String checkSelectedEmployee(EmpUser empUser, MesEmployee employee) {
  660. if (employee == null || StringUtils.isBlank(employee.getUserCode())) {
  661. return null;
  662. }
  663. if (StringUtils.isNotBlank(empUser.getUserCode())
  664. && StringUtils.equals(employee.getUserCode(), empUser.getUserCode())) {
  665. return null;
  666. }
  667. // 员工关联账号若为软删残留,硬删后允许重新开户
  668. User linked = findUserByLoginCodeIncludeDeleted(employee.getLoginCode());
  669. if (linked == null) {
  670. try {
  671. linked = userService.get(new User(employee.getUserCode()));
  672. } catch (Exception ignored) {
  673. linked = null;
  674. }
  675. }
  676. if (linked != null && User.STATUS_DELETE.equals(linked.getStatus())) {
  677. phyDeleteUserByCode(linked.getUserCode());
  678. return null;
  679. }
  680. if (linked != null) {
  681. return "保存用户失败,该员工已创建账号:"
  682. + StringUtils.defaultIfBlank(linked.getLoginCode(), linked.getUserCode());
  683. }
  684. return "保存用户失败,该员工已创建账号:"
  685. + StringUtils.defaultIfBlank(employee.getLoginCode(), employee.getUserCode());
  686. }
  687. private User findBoundUser(MesEmployee employee) {
  688. if (employee == null || StringUtils.isBlank(employee.getEmpCode())) {
  689. return null;
  690. }
  691. User query = new User();
  692. query.setUserType("employee");
  693. query.setRefCode(employee.getEmpCode());
  694. return userService.getByUserTypeAndRefCode(query);
  695. }
  696. private void bindSelectedEmployeeUser(EmpUser empUser, MesEmployee employee) {
  697. empUser.setUserType("employee");
  698. if (StringUtils.isBlank(empUser.getMgrType())) {
  699. empUser.setMgrType("0");
  700. }
  701. empUser.setRefCode(employee.getEmpCode());
  702. empUser.setRefName(employee.getEmpName());
  703. empUser.setEmployee(null);
  704. }
  705. /**
  706. * 按登录账号查询用户(含已删除,用于清理软删残留)
  707. */
  708. private User findUserByLoginCodeIncludeDeleted(String loginCode) {
  709. if (StringUtils.isBlank(loginCode)) {
  710. return null;
  711. }
  712. User query = new User();
  713. query.setLoginCode(loginCode);
  714. User user = userService.getByLoginCode(query);
  715. if (user != null) {
  716. return user;
  717. }
  718. try {
  719. return jdbcTemplate.query(
  720. "SELECT user_code, login_code, user_type, status FROM js_sys_user WHERE login_code = ? LIMIT 1",
  721. rs -> {
  722. if (!rs.next()) {
  723. return null;
  724. }
  725. User u = new User(rs.getString("user_code"));
  726. u.setLoginCode(rs.getString("login_code"));
  727. u.setUserType(rs.getString("user_type"));
  728. u.setStatus(rs.getString("status"));
  729. return u;
  730. }, loginCode);
  731. } catch (EmptyResultDataAccessException e) {
  732. return null;
  733. }
  734. }
  735. /**
  736. * 物理删除用户及角色/数据权限关联,并同步硬删员工档案
  737. * @param userCode 用户编码
  738. * @param empCode 员工编码(可空,空时尝试用 userCode / ref 兜底)
  739. */
  740. private void phyDeleteUserAndEmployee(String userCode, String empCode) {
  741. if (StringUtils.isBlank(userCode) && StringUtils.isBlank(empCode)) {
  742. return;
  743. }
  744. String resolvedEmpCode = empCode;
  745. if (StringUtils.isBlank(resolvedEmpCode) && StringUtils.isNotBlank(userCode)) {
  746. try {
  747. resolvedEmpCode = jdbcTemplate.query(
  748. "SELECT ref_code FROM js_sys_user WHERE user_code = ? LIMIT 1",
  749. rs -> rs.next() ? rs.getString("ref_code") : null,
  750. userCode);
  751. } catch (EmptyResultDataAccessException ignored) {
  752. resolvedEmpCode = null;
  753. }
  754. if (StringUtils.isBlank(resolvedEmpCode)) {
  755. resolvedEmpCode = userCode;
  756. }
  757. }
  758. if (StringUtils.isNotBlank(userCode)) {
  759. phyDeleteUserByCode(userCode);
  760. }
  761. if (StringUtils.isNotBlank(resolvedEmpCode)) {
  762. phyDeleteEmployeeByCode(resolvedEmpCode);
  763. }
  764. }
  765. /**
  766. * 物理删除用户及角色/数据权限关联
  767. */
  768. private void phyDeleteUserByCode(String userCode) {
  769. if (StringUtils.isBlank(userCode)) {
  770. return;
  771. }
  772. jdbcTemplate.update("DELETE FROM js_sys_user_role WHERE user_code = ?", userCode);
  773. jdbcTemplate.update("DELETE FROM js_sys_user_data_scope WHERE user_code = ?", userCode);
  774. jdbcTemplate.update("DELETE FROM js_sys_user WHERE user_code = ?", userCode);
  775. }
  776. /**
  777. * 物理删除员工及附属机构/岗位关联
  778. */
  779. private void phyDeleteEmployeeByCode(String empCode) {
  780. if (StringUtils.isBlank(empCode)) {
  781. return;
  782. }
  783. jdbcTemplate.update("DELETE FROM js_sys_employee_office WHERE emp_code = ?", empCode);
  784. jdbcTemplate.update("DELETE FROM js_sys_employee_post WHERE emp_code = ?", empCode);
  785. jdbcTemplate.update("DELETE FROM js_sys_employee WHERE emp_code = ?", empCode);
  786. }
  787. private boolean hasOtherUser(List<EmpUser> userList, String userCode) {
  788. if (userList == null || userList.isEmpty()) {
  789. return false;
  790. }
  791. for (EmpUser user : userList) {
  792. if (StringUtils.isBlank(userCode) || !StringUtils.equals(userCode, user.getUserCode())) {
  793. return true;
  794. }
  795. }
  796. return false;
  797. }
  798. }