需求开发

This commit is contained in:
liang.chao 2025-07-01 18:04:58 +08:00
parent 2bb6f4d5ae
commit 76253664d0
20 changed files with 887 additions and 7 deletions

View File

@ -21,6 +21,10 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>

View File

@ -1,7 +1,9 @@
package com.bonus.gs.sub.evaluate.evaluate.beans; package com.bonus.gs.sub.evaluate.evaluate.beans;
import lombok.Data; import lombok.Data;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Pattern;
import java.util.List; import java.util.List;
/** /**

View File

@ -14,6 +14,7 @@ public class TeamGroupBean {
private String subContractor; private String subContractor;
// 所属项目 // 所属项目
private String project; private String project;
private String projectId;
// 班组名称 // 班组名称
private String teamGroupName; private String teamGroupName;
// 班组长 // 班组长
@ -36,5 +37,6 @@ public class TeamGroupBean {
private String workType; private String workType;
private String faceUrl; private String faceUrl;
private String isTeamLeader; private String isTeamLeader;
private Integer teamId;
} }

View File

@ -8,6 +8,7 @@ import com.bonus.gs.sub.evaluate.evaluate.service.OrganizationalService;
import com.bonus.gs.sub.evaluate.manager.controller.BaseController; import com.bonus.gs.sub.evaluate.manager.controller.BaseController;
import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes; import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes;
import com.bonus.gs.sub.evaluate.manager.utils.GlobalConst; import com.bonus.gs.sub.evaluate.manager.utils.GlobalConst;
import com.bonus.gs.sub.evaluate.manager.utils.UserUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
@ -175,6 +177,21 @@ public class OrganizationalController extends BaseController<EvaluateBean> {
} }
return ar; return ar;
} }
@RequestMapping(value = "getProjectSelect", method = RequestMethod.POST)
@ResponseBody
public AjaxRes getProjectSelect(OrganizationalBean bean) {
AjaxRes ar = getAjaxRes();
try {
List<OrganizationalBean> list = service.getProjectSelect(bean);
ar.setSucceed(list);
} catch (Exception e) {
logger.error(e.toString(), e);
ar.setFailMsg(GlobalConst.DATA_FAIL);
}
return ar;
}
/** /**
* 获取班组类型下拉框 * 获取班组类型下拉框
@ -269,6 +286,15 @@ public class OrganizationalController extends BaseController<EvaluateBean> {
public AjaxRes getsubcontractorId(@ModelAttribute OrganizationalBean bean, public AjaxRes getsubcontractorId(@ModelAttribute OrganizationalBean bean,
@RequestParam("file") MultipartFile file) { @RequestParam("file") MultipartFile file) {
AjaxRes ar = getAjaxRes(); AjaxRes ar = getAjaxRes();
if (!UserUtil.isPhone(bean.getUserPhone())){
ar.setFailMsg("手机号格式错误");
return ar;
}
if (!UserUtil.isIdCard(bean.getIdCard())){
ar.setFailMsg("身份证号格式错误");
return ar;
}
try { try {
if (file != null && !file.isEmpty()) { if (file != null && !file.isEmpty()) {
// 验证文件类型 // 验证文件类型

View File

@ -4,15 +4,30 @@ import com.bonus.gs.sub.evaluate.evaluate.beans.OrganizationalBean;
import com.bonus.gs.sub.evaluate.evaluate.beans.ProjectBean; import com.bonus.gs.sub.evaluate.evaluate.beans.ProjectBean;
import com.bonus.gs.sub.evaluate.evaluate.beans.TeamGroupBean; import com.bonus.gs.sub.evaluate.evaluate.beans.TeamGroupBean;
import com.bonus.gs.sub.evaluate.evaluate.service.TeamGroupService; import com.bonus.gs.sub.evaluate.evaluate.service.TeamGroupService;
import com.bonus.gs.sub.evaluate.manager.controller.BaseController;
import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes; import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes;
import com.bonus.gs.sub.evaluate.manager.utils.GlobalConst; import com.bonus.gs.sub.evaluate.manager.utils.GlobalConst;
import com.bonus.gs.sub.evaluate.manager.utils.UserUtil;
import com.bonus.gs.sub.evaluate.outsourceEnterprise.beans.ImportUserDataVo;
import com.bonus.gs.sub.evaluate.outsourceEnterprise.beans.ViolationBean;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @Authorliang.chao * @Authorliang.chao
@ -20,7 +35,7 @@ import java.util.List;
*/ */
@RestController @RestController
@RequestMapping("/teamGroup") @RequestMapping("/teamGroup")
public class TeamGroupController { public class TeamGroupController extends BaseController<TeamGroupBean> {
@Autowired @Autowired
private TeamGroupService teamGroupService; private TeamGroupService teamGroupService;
@ -68,11 +83,31 @@ public class TeamGroupController {
} }
return ar; return ar;
} }
// 获取班组人员-综合查询
@GetMapping("getTeamGroupPersons")
public AjaxRes getTeamGroupPersons(TeamGroupBean teamGroupBean) {
AjaxRes ar = new AjaxRes();
try {
List<TeamGroupBean> teamGroupList = teamGroupService.getTeamGroupPersons(teamGroupBean);
ar.setListSucceed(teamGroupList);
} catch (Exception e) {
ar.setFailMsg(GlobalConst.DATA_FAIL);
}
return ar;
}
@PostMapping("addTeamGroupPerson") @PostMapping("addTeamGroupPerson")
public AjaxRes addTeamGroupPerson(@ModelAttribute TeamGroupBean bean, public AjaxRes addTeamGroupPerson(@ModelAttribute TeamGroupBean bean,
@RequestParam("file") MultipartFile file) { @RequestParam("file") MultipartFile file) {
AjaxRes ar = new AjaxRes(); AjaxRes ar = new AjaxRes();
if (!UserUtil.isPhone(bean.getPhone())){
ar.setFailMsg("手机号格式错误");
return ar;
}
if (!UserUtil.isIdCard(bean.getIdCard())){
ar.setFailMsg("身份证号格式错误");
return ar;
}
try { try {
if (file != null && !file.isEmpty()) { if (file != null && !file.isEmpty()) {
// 验证文件类型 // 验证文件类型
@ -102,6 +137,14 @@ public class TeamGroupController {
public AjaxRes updateTeamPerson(@ModelAttribute TeamGroupBean bean, public AjaxRes updateTeamPerson(@ModelAttribute TeamGroupBean bean,
@RequestParam(value = "file", required = false)MultipartFile file) { @RequestParam(value = "file", required = false)MultipartFile file) {
AjaxRes ar = new AjaxRes(); AjaxRes ar = new AjaxRes();
if (!UserUtil.isPhone(bean.getPhone())){
ar.setFailMsg("手机号格式错误");
return ar;
}
if (!UserUtil.isIdCard(bean.getIdCard())){
ar.setFailMsg("身份证号格式错误");
return ar;
}
try { try {
if (file != null && !file.isEmpty()) { if (file != null && !file.isEmpty()) {
// 验证文件类型 // 验证文件类型
@ -144,4 +187,11 @@ public class TeamGroupController {
} }
return ar; return ar;
} }
@RequestMapping(value = "importTeamPerson", method = RequestMethod.POST)
@ResponseBody
public AjaxRes importTeamPerson(@RequestParam("file") MultipartFile file) {
return teamGroupService.importTeamPerson(file);
}
} }

View File

@ -183,4 +183,8 @@ public interface OrganizationalDao{
Integer insetTeamPerson(OrganizationalBean bean); Integer insetTeamPerson(OrganizationalBean bean);
List<OrganizationalBean> getWorkType(OrganizationalBean bean); List<OrganizationalBean> getWorkType(OrganizationalBean bean);
List<OrganizationalBean> getProjectSelect(OrganizationalBean bean);
int getUser(OrganizationalBean bean);
} }

View File

@ -3,6 +3,7 @@ package com.bonus.gs.sub.evaluate.evaluate.dao;
import com.bonus.gs.sub.evaluate.evaluate.beans.ProjectBean; import com.bonus.gs.sub.evaluate.evaluate.beans.ProjectBean;
import com.bonus.gs.sub.evaluate.evaluate.beans.TeamGroupBean; import com.bonus.gs.sub.evaluate.evaluate.beans.TeamGroupBean;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -39,4 +40,18 @@ public interface TeamGroupDao {
Integer isTeamLeader(TeamGroupBean teamGroupBean); Integer isTeamLeader(TeamGroupBean teamGroupBean);
Integer delTeamPerson(TeamGroupBean teamGroupBean); Integer delTeamPerson(TeamGroupBean teamGroupBean);
List<String> checkExistIdCards(@Param("idCards") List<String> idCards);
List<String> checkExistPhones(@Param("phones") List<String> phones);
Integer getIdByName(@Param("name") String teamName);
Integer batchInsert(List<TeamGroupBean> teamPersons);
String getWorkTypeId(String workType);
String selectTeamLeaser(TeamGroupBean groupBean);
List<TeamGroupBean> getTeamGroupPersons(TeamGroupBean teamGroupBean);
} }

View File

@ -78,4 +78,6 @@ public interface OrganizationalService{
AjaxRes addTeamGroup(OrganizationalBean bean); AjaxRes addTeamGroup(OrganizationalBean bean);
List<OrganizationalBean> getWorkType(OrganizationalBean bean); List<OrganizationalBean> getWorkType(OrganizationalBean bean);
List<OrganizationalBean> getProjectSelect(OrganizationalBean bean);
} }

View File

@ -352,7 +352,7 @@ public class OrganizationalServiceImpl implements OrganizationalService {
// 根据外包商id(project_assignment)和项目id获取组织架构(pm_org_info)中外包商id // 根据外包商id(project_assignment)和项目id获取组织架构(pm_org_info)中外包商id
String id = mapper.getsubcontractorId(bean); String id = mapper.getsubcontractorId(bean);
bean.setParentId(id); bean.setParentId(id);
int userNum = mapper.getUserNum(bean); int userNum = mapper.getUser(bean);
if (userNum > 0) { if (userNum > 0) {
ar.setFailMsg("该人员已存在"); ar.setFailMsg("该人员已存在");
return ar; return ar;
@ -386,6 +386,11 @@ public class OrganizationalServiceImpl implements OrganizationalService {
return mapper.getWorkType(bean); return mapper.getWorkType(bean);
} }
@Override
public List<OrganizationalBean> getProjectSelect(OrganizationalBean bean) {
return mapper.getProjectSelect(bean);
}
public static List<OrganizationalBean> buildTree(List<OrganizationalBean> nodes) { public static List<OrganizationalBean> buildTree(List<OrganizationalBean> nodes) {
// 根节点是没有父节点的节点 // 根节点是没有父节点的节点
List<OrganizationalBean> rootNodes = nodes.stream() List<OrganizationalBean> rootNodes = nodes.stream()

View File

@ -3,6 +3,7 @@ package com.bonus.gs.sub.evaluate.evaluate.service;
import com.bonus.gs.sub.evaluate.evaluate.beans.ProjectBean; import com.bonus.gs.sub.evaluate.evaluate.beans.ProjectBean;
import com.bonus.gs.sub.evaluate.evaluate.beans.TeamGroupBean; import com.bonus.gs.sub.evaluate.evaluate.beans.TeamGroupBean;
import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes; import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes;
import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
@ -24,4 +25,8 @@ public interface TeamGroupService {
AjaxRes updateTeamPerson(TeamGroupBean teamGroupBean); AjaxRes updateTeamPerson(TeamGroupBean teamGroupBean);
Integer delTeamPerson(TeamGroupBean teamGroupBean); Integer delTeamPerson(TeamGroupBean teamGroupBean);
AjaxRes importTeamPerson(MultipartFile file);
List<TeamGroupBean> getTeamGroupPersons(TeamGroupBean teamGroupBean);
} }

View File

@ -3,10 +3,19 @@ package com.bonus.gs.sub.evaluate.evaluate.service;
import com.bonus.gs.sub.evaluate.evaluate.beans.TeamGroupBean; import com.bonus.gs.sub.evaluate.evaluate.beans.TeamGroupBean;
import com.bonus.gs.sub.evaluate.evaluate.dao.TeamGroupDao; import com.bonus.gs.sub.evaluate.evaluate.dao.TeamGroupDao;
import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes; import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes;
import com.bonus.gs.sub.evaluate.manager.utils.UserUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/** /**
* @Authorliang.chao * @Authorliang.chao
@ -20,7 +29,11 @@ public class TeamGroupServiceImpl implements TeamGroupService {
@Override @Override
public List<TeamGroupBean> getTeamGroupList(TeamGroupBean teamGroupBean) { public List<TeamGroupBean> getTeamGroupList(TeamGroupBean teamGroupBean) {
return teamGroupDao.getTeamGroupList(teamGroupBean); List<TeamGroupBean> teamGroupList = teamGroupDao.getTeamGroupList(teamGroupBean);
for (TeamGroupBean groupBean : teamGroupList) {
groupBean.setTeamLeader(teamGroupDao.selectTeamLeaser(groupBean));
}
return teamGroupList;
} }
@Override @Override
@ -96,4 +109,233 @@ public class TeamGroupServiceImpl implements TeamGroupService {
return teamGroupDao.delTeamPerson(teamGroupBean); return teamGroupDao.delTeamPerson(teamGroupBean);
} }
} }
@Override
public AjaxRes importTeamPerson(MultipartFile file) {
AjaxRes ar = new AjaxRes();
List<Map<String, String>> successList = new ArrayList<>();
try (InputStream inputStream = file.getInputStream()) {
Workbook workbook = WorkbookFactory.create(inputStream);
// 获取第一个sheet
Sheet sheet = workbook.getSheetAt(0);
// 验证表头
if (!validateHeader(sheet.getRow(1))) {
ar.setFailMsg("Excel模板不正确请下载最新模板");
return ar;
}
// 收集所有身份证和手机号用于批量校验
List<String> idCards = new ArrayList<>();
List<String> phones = new ArrayList<>();
for (int i = 2; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row == null) continue;
String idCard = getCellValue(row.getCell(2));
String phone = getCellValue(row.getCell(3));
if (StringUtils.isBlank(idCard)) {
ar.setFailMsg("身份证号不能为空");
return ar;
}
if (StringUtils.isBlank(phone)) {
ar.setFailMsg("手机号不能为空");
return ar;
}
if (!UserUtil.isPhone(phone)) {
ar.setFailMsg(phone + "手机号格式错误");
return ar;
}
if (!UserUtil.isIdCard(idCard)) {
ar.setFailMsg(idCard + "身份证号格式错误");
return ar;
}
idCards.add(idCard);
phones.add(phone);
}
// 找出模版中重复元素
List<String> repeatidCardlist = idCards.stream()
.filter(id -> Collections.frequency(idCards, id) > 1)
.distinct() // 去重避免同一个元素多次出现在结果中
.collect(Collectors.toList());
if (!repeatidCardlist.isEmpty()) {
ar.setFailMsg("身份证号" + repeatidCardlist + "重复,请检查");
return ar;
}
List<String> repeatPhonelist = phones.stream()
.filter(id -> Collections.frequency(phones, id) > 1)
.distinct() // 去重避免同一个元素多次出现在结果中
.collect(Collectors.toList());
if (!repeatPhonelist.isEmpty()) {
ar.setFailMsg("手机号" + repeatPhonelist + "重复,请检查");
return ar;
}
// 批量检查身份证和手机号是否已存在
Map<String, Boolean> existIdCards = checkExistIdCards(idCards);
Map<String, Boolean> existPhones = checkExistPhones(phones);
// 处理每一行数据
for (int i = 2; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row == null) continue;
Map<String, String> rowData = processRow(row, existIdCards, existPhones);
if (rowData.containsKey("error")) {
ar.setFailMsg(rowData.get("error"));
return ar;
} else {
successList.add(rowData);
}
}
// 批量插入有效数据
if (!successList.isEmpty()) {
List<TeamGroupBean> teamPersons = successList.stream()
.map(this::convertToTeamPerson)
.collect(Collectors.toList());
Integer i = teamGroupDao.batchInsert(teamPersons);
if (i > 0) {
ar.setSucceed("成功导入" + successList.size() + "条数据");
}
}
return ar;
} catch (Exception e) {
ar.setFailMsg("文件读取失败");
return ar;
}
}
@Override
public List<TeamGroupBean> getTeamGroupPersons(TeamGroupBean teamGroupBean) {
return teamGroupDao.getTeamGroupPersons(teamGroupBean);
}
// 处理单行数据
private Map<String, String> processRow(Row row, Map<String, Boolean> existIdCards, Map<String, Boolean> existPhones) {
Map<String, String> rowData = new HashMap<>();
StringBuilder errorMsg = new StringBuilder();
// 获取单元格值
String teamName = getCellValue(row.getCell(0));
String name = getCellValue(row.getCell(1));
String idCard = getCellValue(row.getCell(2));
String phone = getCellValue(row.getCell(3));
String sex = getCellValue(row.getCell(4));
String workType = getCellValue(row.getCell(5));
// 校验班组名称是否存在
Integer teamId = teamGroupDao.getIdByName(teamName);
if (teamId == null) {
errorMsg.append(teamName + "名称不存在; ");
}
// 校验身份证
if (idCard == null || idCard.isEmpty()) {
errorMsg.append("身份证不能为空; ");
} else if (existIdCards.getOrDefault(idCard, false)) {
// 如果模版中有身份证号重复
errorMsg.append(idCard + "身份证号已存在; ");
}
// 校验手机号
if (phone != null && !phone.isEmpty() && existPhones.getOrDefault(phone, false)) {
// 如果模版中有身份证号重复
errorMsg.append(phone + "手机号已存在; ");
}
// 校验性别
if (sex == null || (!"".equals(sex) && !"".equals(sex))) {
errorMsg.append("性别格式不正确(应为男或女); ");
} else {
sex = sex.equals("") ? "1" : "2";
}
if (StringUtils.isBlank(workType)) {
errorMsg.append("工种不能为空; ");
} else {
workType = teamGroupDao.getWorkTypeId(workType);
if (workType == null) {
errorMsg.append("系统中不存在" + workType + "工种");
}
}
// 如果有错误返回错误信息
if (errorMsg.length() > 0) {
rowData.put("error", "" + (row.getRowNum() + 1) + "行中" + errorMsg);
return rowData;
}
// 如果没有错误保存数据
rowData.put("teamId", String.valueOf(teamId));
rowData.put("name", name);
rowData.put("idCard", idCard);
rowData.put("phone", phone);
rowData.put("sex", sex);
rowData.put("workType", workType);
rowData.put("isLeader", "1");
return rowData;
}
private boolean validateHeader(Row headerRow) {
if (headerRow == null) return false;
return "班组名称".equals(getCellValue(headerRow.getCell(0))) &&
"姓名".equals(getCellValue(headerRow.getCell(1))) &&
"身份证".equals(getCellValue(headerRow.getCell(2))) &&
"电话".equals(getCellValue(headerRow.getCell(3))) &&
"性别".equals(getCellValue(headerRow.getCell(4))) &&
"工种".equals(getCellValue(headerRow.getCell(5)));
}
private TeamGroupBean convertToTeamPerson(Map<String, String> rowData) {
TeamGroupBean person = new TeamGroupBean();
person.setTeamId(Integer.parseInt(rowData.get("teamId")));
person.setName(rowData.get("name"));
person.setIdCard(rowData.get("idCard"));
person.setPhone(rowData.get("phone"));
person.setSex(rowData.get("sex"));
person.setWorkType(rowData.get("workType"));
person.setIsTeamLeader(rowData.get("isLeader"));
return person;
}
// 获取单元格值
private String getCellValue(Cell cell) {
if (cell == null) {
return null;
}
// 创建DataFormatter实例可以定义为类成员变量重用
DataFormatter formatter = new DataFormatter();
// 使用DataFormatter格式化单元格值
return formatter.formatCellValue(cell).trim();
}
// 检查身份证是否已存在
private Map<String, Boolean> checkExistIdCards(List<String> idCards) {
if (idCards.isEmpty()) return new HashMap<>();
List<String> existIdCards = teamGroupDao.checkExistIdCards(idCards);
Map<String, Boolean> result = new HashMap<>();
for (String idCard : idCards) {
result.put(idCard, existIdCards.contains(idCard));
}
return result;
}
// 检查手机号是否已存在
private Map<String, Boolean> checkExistPhones(List<String> phones) {
if (phones.isEmpty()) return new HashMap<>();
List<String> existPhones = teamGroupDao.checkExistPhones(phones);
Map<String, Boolean> result = new HashMap<>();
for (String phone : phones) {
result.put(phone, existPhones.contains(phone));
}
return result;
}
} }

View File

@ -6,6 +6,8 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import java.util.regex.Pattern;
public class UserUtil { public class UserUtil {
public static LoginUser getLoginUser() { public static LoginUser getLoginUser() {
@ -23,4 +25,39 @@ public class UserUtil {
return null; return null;
} }
/**
* 校验身份证号码是否合法支持15位和18位
*
* @param idCard 身份证号码
* @return 是否合法
*/
public static boolean isIdCard(String idCard) {
if (idCard == null || idCard.isEmpty()) {
return false;
}
// 定义15位和18位的正则表达式
String regex15 = "^[1-9]\\d{7}((0[1-9])|(1[0-2]))((0[1-9])|([12][0-9])|(3[01]))\\d{3}$";
String regex18 = "^[1-9]\\d{5}[1-9]\\d{3}((0[1-9])|(1[0-2]))((0[1-9])|([12][0-9])|(3[01]))\\d{3}(\\d|X|x)$";
return Pattern.matches(regex15, idCard) || Pattern.matches(regex18, idCard);
}
/**
* 校验手机号是否为中国大陆手机号
*
* @param phone 手机号
* @return 是否合法
*/
public static boolean isPhone(String phone) {
if (phone == null || phone.isEmpty()) {
return false;
}
// 匹配以 131415171819 开头的11位手机号
String regex = "^1[345789]\\d{9}$";
return Pattern.matches(regex, phone);
}
} }

View File

@ -1,6 +1,8 @@
package com.bonus.gs.sub.evaluate.outsourceEnterprise.controller; package com.bonus.gs.sub.evaluate.outsourceEnterprise.controller;
import com.bonus.gs.sub.evaluate.evaluate.beans.TeamGroupBean;
import com.bonus.gs.sub.evaluate.evaluate.service.TeamGroupService;
import com.bonus.gs.sub.evaluate.manager.controller.BaseController; import com.bonus.gs.sub.evaluate.manager.controller.BaseController;
import com.bonus.gs.sub.evaluate.manager.utils.AesCbcUtils; import com.bonus.gs.sub.evaluate.manager.utils.AesCbcUtils;
import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes; import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes;
@ -45,6 +47,9 @@ public class ViolationController extends BaseController<ViolationBean> {
@Autowired @Autowired
private ViolationDao dao; private ViolationDao dao;
@Autowired
private TeamGroupService teamGroupService;
@GetMapping("outsourceEnterpriseByPage") @GetMapping("outsourceEnterpriseByPage")
@ResponseBody @ResponseBody
@ -186,6 +191,17 @@ public class ViolationController extends BaseController<ViolationBean> {
e.printStackTrace(); e.printStackTrace();
} }
} }
@RequestMapping("exportTeamGroupPerson")
public void exportTeamGroupPerson(HttpServletRequest request, HttpServletResponse response, TeamGroupBean teamGroupBean) {
String filename = "班组人员详情表";
List<TeamGroupBean> teamGroupPersons = teamGroupService.getTeamGroupPersons(teamGroupBean);
// 导出所有人员基本信息
try {
excelOutTeamGroupPersons(response, teamGroupPersons, filename, "班组人员详情表");
} catch (Exception e) {
e.printStackTrace();
}
}
@RequestMapping(value = "toLeadInto", method = RequestMethod.POST) @RequestMapping(value = "toLeadInto", method = RequestMethod.POST)
@ResponseBody @ResponseBody
@ -477,6 +493,29 @@ public class ViolationController extends BaseController<ViolationBean> {
out.close(); out.close();
} }
} }
private void excelOutTeamGroupPersons(HttpServletResponse response, List<TeamGroupBean> registlist, String filename, String sheetname)
throws Exception {
if (registlist != null) {
List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
int size = registlist.size();
for (int i = 0; i < size; i++) {
TeamGroupBean bean = registlist.get(i);
Map<String, Object> maps = outVehicleOilBeanMap(i, bean, sheetname);
results.add(maps);
}
List<String> headers = outVehicleOilHeaders(sheetname);
HSSFWorkbook workbook = POIOutputHelperNumBer.excel(results, headers, filename);
OutputStream out = null;
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.addHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(filename, "UTF-8") + ".xls");
response.setHeader("Pragma", "No-cache");
out = response.getOutputStream();
workbook.write(out);
out.flush();
out.close();
}
}
private Map<String, Object> outVehicleOilBeanMap(int i, ViolationBean bean, String sheetname) { private Map<String, Object> outVehicleOilBeanMap(int i, ViolationBean bean, String sheetname) {
Map<String, Object> maps = new LinkedHashMap<String, Object>(); Map<String, Object> maps = new LinkedHashMap<String, Object>();
@ -534,6 +573,27 @@ public class ViolationController extends BaseController<ViolationBean> {
return maps; return maps;
} }
private Map<String, Object> outVehicleOilBeanMap(int i, TeamGroupBean bean, String sheetname) {
Map<String, Object> maps = new LinkedHashMap<String, Object>();
maps.put("id", i + 1);
switch (sheetname) {
case "班组人员详情表":
maps.put("subContractor", bean.getSubContractor());
maps.put("project", bean.getProject());
maps.put("teamGroupName", bean.getTeamGroupName());
maps.put("name", bean.getName());
maps.put("idCard", bean.getIdCard());
maps.put("phone", bean.getPhone());
maps.put("sex", bean.getSex());
maps.put("workType", bean.getWorkType());
maps.put("isTeamLeader", bean.getIsTeamLeader());
break;
default:
break;
}
return maps;
}
private List<String> outVehicleOilHeaders(String sheetname) { private List<String> outVehicleOilHeaders(String sheetname) {
ArrayList<String> list = new ArrayList<String>(); ArrayList<String> list = new ArrayList<String>();
@ -586,6 +646,17 @@ public class ViolationController extends BaseController<ViolationBean> {
list.add("剩余记分"); list.add("剩余记分");
list.add("违章次数"); list.add("违章次数");
break; break;
case"班组人员详情表":
list.add("所属分包商");
list.add("所属项目");
list.add("所属班组");
list.add("姓名");
list.add("身份证");
list.add("电话");
list.add("性别");
list.add("工种");
list.add("是否班组长");
break;
default: default:
break; break;
} }

View File

@ -309,4 +309,19 @@
from t_dict from t_dict
where type = 'workType' where type = 'workType'
</select> </select>
<select id="getProjectSelect" resultType="com.bonus.gs.sub.evaluate.evaluate.beans.OrganizationalBean">
SELECT
poi.id,
poi.NAME
FROM
pm_org_info poi
WHERE
poi.STATUS = 1
AND poi.LEVEL = 3
</select>
<select id="getUser" resultType="java.lang.Integer">
select count(1)
from team_person
where id_card = #{idCard} or phone = #{userPhone}
</select>
</mapper> </mapper>

View File

@ -9,6 +9,14 @@
values values
(#{id},#{name},#{idCard},#{phone},#{sex},#{workTypeId},#{faceUrl},#{isTeamLeader}) (#{id},#{name},#{idCard},#{phone},#{sex},#{workTypeId},#{faceUrl},#{isTeamLeader})
</insert> </insert>
<insert id="batchInsert">
INSERT INTO team_person (team_id, name, id_card, phone, sex, work_type, is_team_leader)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.teamId}, #{item.name}, #{item.idCard}, #{item.phone},
#{item.sex}, #{item.workType}, #{item.isTeamLeader})
</foreach>
</insert>
<update id="updaTeteamType"> <update id="updaTeteamType">
update team_group_type set team_type = #{teamType} where team_group_id = #{id} update team_group_type set team_type = #{teamType} where team_group_id = #{id}
@ -38,7 +46,6 @@
poi.NAME teamGroupName, poi.NAME teamGroupName,
poi.id as id, poi.id as id,
poi.status as status, poi.status as status,
CONCAT( poi.user_name, '/', poi.user_phone ) teamLeader,
td.id as teamTypeId, td.id as teamTypeId,
td.val teamType, td.val teamType,
count( tp.team_id ) teamPersonNum count( tp.team_id ) teamPersonNum
@ -98,4 +105,65 @@
<select id="isTeamLeader" resultType="java.lang.Integer"> <select id="isTeamLeader" resultType="java.lang.Integer">
select is_team_leader from team_person where id = #{id} select is_team_leader from team_person where id = #{id}
</select> </select>
<select id="checkExistIdCards" resultType="java.lang.String">
SELECT id_card FROM team_person WHERE id_card IN
<foreach collection="idCards" item="idCard" open="(" separator="," close=")">
#{idCard}
</foreach>
</select>
<select id="checkExistPhones" resultType="java.lang.String">
SELECT phone FROM team_person WHERE phone IN
<foreach collection="phones" item="phone" open="(" separator="," close=")">
#{phone}
</foreach>
</select>
<select id="getIdByName" resultType="java.lang.Integer">
SELECT id FROM pm_org_info WHERE name = #{name}
</select>
<select id="getWorkTypeId" resultType="java.lang.String">
SELECT id FROM t_dict WHERE val = #{workType} and type = 'workType'
</select>
<select id="selectTeamLeaser" resultType="java.lang.String">
SELECT CONCAT( name, ' / ', phone ) FROM team_person WHERE team_id = #{id} and is_team_leader = 0
</select>
<select id="getTeamGroupPersons" resultType="com.bonus.gs.sub.evaluate.evaluate.beans.TeamGroupBean">
SELECT tp.id,
tp.name,
poi.name as teamGroupName,
poi2.name as subContractor,
poi3.name as project,
tp.id_card as idCard,
tp.phone,
case when tp.sex = 1 then '男' else '女' end as sex,
tp.work_type workTypeId,
td.val as workType,
tp.face_url as faceUrl,
case when tp.is_team_leader = 0 then '是' else '否' end as isTeamLeader
FROM
team_person tp
left join t_dict td on tp.work_type = td.id
left join pm_org_info poi on tp.team_id = poi.id
left join pm_org_info poi2 on poi2.id = poi.parent_id
left join pm_org_info poi3 on poi3.id = poi2.parent_id
WHERE 1=1
<if test="keyWord != null and keyWord != ''">
AND (
poi2.NAME like concat('%',#{keyWord},'%') or
poi3.NAME like concat('%',#{keyWord},'%') or
poi.NAME like concat('%',#{keyWord},'%')
)
</if>
<if test="name != null and name != ''">
and tp.name like concat('%',#{name},'%')
</if>
<if test="sex != null and sex != ''">
and tp.sex = #{sex}
</if>
<if test="projectId != null and projectId != ''">
and poi3.id = #{projectId}
</if>
<if test="workType != null and workType != ''">
and tp.work_type = #{workType}
</if>
</select>
</mapper> </mapper>

View File

@ -264,3 +264,52 @@ function addPerson() {
}, },
}); });
} }
function importTemplate() {
let token = localStorage.getItem("token");
window.location.href =ctxPath + "/backstage/download?filename=班组人员导入模版.xls&token=" + token;
}
function importData() {
var formData = new FormData($('form')[0]);
var name = $("#articleImageFile").val();
if (name == null || name == "") {
return;
}
if (!(name.endsWith(".xls") || name.endsWith(".xlsx") || name.endsWith(".xlsm"))) {
alert("请上传正确的Excel表格!");
$("#articleImageFile").val("");
return;
}
formData.append("file", $("#articleImageFile")[0].files[0]);
var idx = layer.msg('正在提交数据,请稍等...', {
icon: 16
, shade: 0.01
, time: '-1'
});
$.ajax({
url: ctxPath + "/teamGroup/importTeamPerson",
type: 'POST',
async: true,
data: formData,
timeout: 20000,
// 告诉jQuery不要去处理发送的数据
processData: false,
// 告诉jQuery不要去设置Content-Type请求头
contentType: false,
success: function (data) {
if (data.res === 0) {
layer.close(idx);
layer.msg('导入失败' + data.resMsg, { icon: 2, time: 2000 });
} else {
layer.close(idx);
layer.msg('导入成功', { icon: 1, time: 2000 });
search(1)
}
},
error: function (data) {
layer.close(idx);
layer.msg('导入失败', {icon: 2, time: 2000});
}
});
$("#articleImageFile").val("");
}

View File

@ -0,0 +1,183 @@
// 专责审批 js文件
let layer, laydate, table, form;
let fileList = [];
$(function () {
layui.use(["layer", "laydate", "table", "form"], function () {
layer = layui.layer;
laydate = layui.laydate;
form = layui.form;
table = layui.table;
laydate.render({
elem: "#startDate",
type: "month",
format: "yyyy-MM",
});
getProjects();
getWorkType();
initTable();
});
});
// 获取项目(工程)下拉框
function getWorkType() {
$.ajax({
type: 'POST',
url: ctxPath + '/organizational/getWorkType',
success: function (data) {
setSelectValue(data.obj, 'workType', "id", "name", "工种");
}
});
}
// 获取工种类型下拉框
function getProjects() {
$.ajax({
url: `${ctxPath}` + "/organizational/getProjectSelect",
type: "post",
data: {},
dataType: "JSON",
success: function (result) {
if (result.res === 1) {
setSelectValue(result.obj, "project", "id", "name", "所属工程");
}
},
});
}
function setSelectValue(list, selectName, code, nameCode, name) {
let html = `<option value="">请选择${name}</option>`;
if (list && list.length > 0) {
$.each(list, function (index, item) {
html +=
"<option value='" +
item[code] +
"' item='" +
JSON.stringify(item) +
"'>" +
item[nameCode] +
"</option>";
});
}
$("#" + selectName)
.empty()
.append(html);
layui.form.render();
}
function search(type) {
if (type === 1) {
} else {
$("#keyWord").val("");
$("#name").val("");
$("#project").val("");
$("#sex").val("");
$("#workType").val("");
form.render("select");
}
table.reload("baseTable", {
url: ctxPath + "/teamGroup/getTeamGroupPersons",
page: {
curr: 1,
},
where: {
type: "audit",
keyWord: $("#keyWord").val(),
name: $("#name").val(),
projectId: $("#project").val(),
sex: $("#sex").val(),
workType: $("#workType").val(),
},
});
}
function initTable() {
//渲染表格
table.render({
elem: "#baseTable",
url: ctxPath + "/teamGroup/getTeamGroupPersons",
method: "get", //方式默认是get
toolbar: "default", //开启工具栏,此处显示默认图标,可以自定义模板,详见文档
where: {
type: "audit",
},
cellMinWidth: 80,
cols: [
[
//表头
{
field: "number",
width: 80,
title: "序号",
align: "center",
type: "numbers",
},
{field: "subContractor", align: "center", title: "所属分包商"},
{field: "project", align: "center", title: "所属项目"},
{field: "teamGroupName", align: "center", title: "所属班组"},
{field: "name", align: "center", title: "姓名"},
{field: "idCard", align: "center", title: "身份证"},
{field: "phone", align: "center", title: "电话"},
{field: "sex", align: "center", title: "性别"},
{field: "workType", align: "center", title: "工种"},
{
field: "faceUrl",
align: "center",
title: "人脸",
templet: function (d) {
return '<a onclick="openFaceUrlPage(' + d.id + ')" style="color: #1E9FFF; cursor: pointer;"> 查看 </a>';
}
},
{field: "isTeamLeader", align: "center", title: "是否班组长"},
],
],
id: "baseTable",
page: true, //开启分页
loading: true, //数据加载中。。。
limits: [10, 20, 100], //一页选择显示3,5或10条数据
limit: 10, //一页显示5条数据
response: {
statusCode: 200, //规定成功的状态码默认0
},
parseData: function (res) {
//将原始数据解析成 table 组件所规定的数据res为从url中get到的数据
let result;
if (res.data !== "" && res.data != null && res.data !== "null") {
fileList = res.data;
if (this.page.curr) {
result = res.data.slice(
this.limit * (this.page.curr - 1),
this.limit * this.page.curr
);
} else {
result = res.data.slice(0, this.limit);
}
}
return {
code: res.code, //解析接口状态
msg: res.msg, //解析提示文本
count: res.count, //解析数据长度
data: result, //解析数据列表
};
},
toolbar: "#toolbar",
});
}
// 预览文件
function openFaceUrlPage(id) {
const filePath = ctxPath + "/statics/" + fileList.filter(item => item.id == id)[0].faceUrl
window.open(filePath)
}
function exporTeamGroupPersons() {
console.log("导出")
const params = {
keyWord: $("#keyWord").val(),
name: $("#name").val(),
projectId: $("#project").val(),
sex: $("#sex").val(),
workType: $("#workType").val(),
};
let token = localStorage.getItem("token");
$(location).attr("href", ctxPath + '/backstage/violations/exportTeamGroupPerson?' + $.param(params) + "&token=" + token);
}

View File

@ -28,6 +28,12 @@
color: #428bca; color: #428bca;
text-decoration: none; text-decoration: none;
} }
.layui-input {
display: block;
width: 100%;
padding: 6px;
}
</style> </style>
</head> </head>
<body> <body>
@ -36,9 +42,8 @@
<form id="baseForm" class="layui-form" method="POST" onsubmit="return false;"> <form id="baseForm" class="layui-form" method="POST" onsubmit="return false;">
<div class="layui-row" style="display: flex;flex-direction: row;padding: 10px;width: 98%"> <div class="layui-row" style="display: flex;flex-direction: row;padding: 10px;width: 98%">
<!-- 姓名 --> <!-- 姓名 -->
<label class="layui-form-label"><span class="required_icon">*</span>姓名</label>
<div class="layui-input-inline"> <div class="layui-input-inline">
<input type="text" required lay-verify="required" id="name" <input type="text" required lay-verify="required" id="name" placeholder="请输入姓名"
name="name" autocomplete="off" class="layui-input"> name="name" autocomplete="off" class="layui-input">
</div> </div>
<select id="sex" class="layui-select" name="sex"> <select id="sex" class="layui-select" name="sex">
@ -53,6 +58,14 @@
<button type="button" class="layui-btn layui-bg-blue" onclick="addPerson();" style="float:right;"> <button type="button" class="layui-btn layui-bg-blue" onclick="addPerson();" style="float:right;">
新增 新增
</button> </button>
<button class="layui-btn" title="导入模板下载" type="button" onclick="importTemplate()">
导入模板下载
</button>
<input id="articleImageFile" type="file" class="layui-input" style="width: 200px; display: inline;margin-left: 2%;margin-right: 10px;"/>
<button class="layui-btn " title="批量导入" type="button"
onclick="importData()">
批量导入
</button>
</div> </div>
</form> </form>
<div id="tree-table-box" style="padding: 10px"> <div id="tree-table-box" style="padding: 10px">

View File

@ -0,0 +1,87 @@
<!Doctype html>
<html lang="">
<head>
<title>外包企业管理</title>
<link rel="stylesheet" href="../../../layui/css/layui.css"/>
<style>
#tree-table-box table thead th {
font-size: 16px;
font-weight: bold;
color: #404040;
}
.layui-table thead tr {
background-color: #f0f0f0;
height: 50px;
}
.layui-table td, .layui-table th, .layui-table-col-set, .layui-table-fixed-r, .layui-table-grid-down, .layui-table-header, .layui-table-mend, .layui-table-page, .layui-table-tips-main, .layui-table-tool, .layui-table-total, .layui-table-view, .layui-table[lay-skin=line], .layui-table[lay-skin=row] {
border-color: #ddd;
}
a:hover, a:focus {
color: #2a6496;
text-decoration: underline;
}
a {
color: #428bca;
text-decoration: none;
}
.layui-input {
display: block;
width: 100%;
padding: 6px;
}
</style>
</head>
<body>
<div class="row-fluid" style="padding: 10px">
<div class="col-xs-12">
<form id="baseForm" class="layui-form" method="POST" onsubmit="return false;">
<div class="layui-row" style="display: flex;flex-direction: row;padding: 10px;width: 98%">
<!-- 关键字 -->
<input type="text" style="width: 20%;" name="keyWord" id="keyWord"
lay-verify="required"
placeholder="请输入关键字"
autocomplete="off"
class="layui-input">
<!-- 人员姓名 -->
<div class="layui-input-inline">
<input type="text" required lay-verify="required" id="name" placeholder="请输入姓名"
name="name" autocomplete="off" class="layui-input">
</div>
<!-- 所属工程 -->
<select id="project" class="layui-select" name="project">
</select>
<select id="sex" class="layui-select" name="sex">
<option value="">请选择性别</option>
<option value="1"></option>
<option value="2"></option>
</select>
<!-- 工种 -->
<select id="workType" class="layui-select" name="workType">
</select>
<button type="button" class="layui-btn layui-bg-blue" style="margin-left: 10px;"
onclick="search(1)">查询
</button>
<button type="button" class="layui-btn layui-bg-blue" onclick="search(2)">重置</button>
<button class="layui-btn" title="v" type="button" onclick="exporTeamGroupPersons()">导出</button>
</div>
</form>
<div id="tree-table-box" style="padding: 10px">
<table id="baseTable" class="layui-table" lay-filter="test"></table>
</div>
</div>
</div>
<script src="../../../js/publicJs.js"></script>
<script type="text/javascript" src="../../../js/libs/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="../../../js/jq.js"></script>
<script type="text/javascript" src="../../../js/my/permission.js"></script>
<script type="text/javascript" src="../../../js/select.js"></script>
<script src="../../../layui/layui.js"></script>
<script src="../../../js/evaluate/teamGroup/teamMemBerPerson.js?v=1"></script>
</body>
</html>