人力成本管理
parent
e63c385be1
commit
e2e24f6f77
|
@ -71,6 +71,10 @@ dependencies {
|
|||
compile group: 'org.apache.xmlgraphics', name: 'batik-codec', version: '1.7'
|
||||
/*activiti end*/
|
||||
|
||||
// https://mvnrepository.com/artifact/cn.afterturn/easypoi-base
|
||||
compile group: 'cn.afterturn', name: 'easypoi-base', version: '4.2.0'
|
||||
// https://mvnrepository.com/artifact/cn.afterturn/easypoi-annotation
|
||||
compile group: 'cn.afterturn', name: 'easypoi-annotation', version: '4.2.0'
|
||||
|
||||
compileOnly 'org.springframework.boot:spring-boot-configuration-processor'
|
||||
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
package cn.palmte.work.controller.backend;
|
||||
|
||||
import cn.palmte.work.bean.ResponseMsg;
|
||||
import cn.palmte.work.model.*;
|
||||
import cn.palmte.work.service.HumanCostService;
|
||||
import cn.palmte.work.utils.Utils;
|
||||
import cn.palmte.work.utils.excel.ExcelUtil;
|
||||
import cn.palmte.work.utils.excel.ExportUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.apache.poi.EncryptedDocumentException;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import top.jfunc.common.db.bean.Page;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 人力成本管理
|
||||
* @author Yuanping Zhang
|
||||
* @date 2021/11/1
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/humanCost")
|
||||
public class HumanCostController extends BaseController{
|
||||
private static final Logger logger = LoggerFactory.getLogger(HumanCostController.class);
|
||||
|
||||
@Autowired
|
||||
private DeptRepository deptRepository;
|
||||
|
||||
@Autowired
|
||||
private HumanCostService humanCostService;
|
||||
|
||||
@Autowired
|
||||
private AdminRepository adminRepository;
|
||||
|
||||
@Autowired
|
||||
private ProjectRepository projectRepository;
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@RequestMapping("/list")
|
||||
public String list(@RequestParam(value = KEYWORDS,required = false) String keywords,
|
||||
@RequestParam(value = PAGE_NUMBER, defaultValue = DEFAULT_PAGE_NUMBER) int pageNumber,
|
||||
@RequestParam(value = PAGE_SIZE, defaultValue = DEFAULT_PAGE_SIZE) int pageSize,
|
||||
Map<String, Object> model) {
|
||||
//当前登录人的角色类型
|
||||
Admin admin = getAdmin();
|
||||
int roleId = admin.getRoleId();
|
||||
List<Project> selfProjects = projectRepository.findByCreator(admin.getId(), new Date());
|
||||
if (roleId <= 18) {
|
||||
model.put("deptVary", 1);
|
||||
model.put("deptList", deptRepository.findAll());
|
||||
model.put("projectList", projectRepository.findAll());
|
||||
model.put("showSalary", 1);
|
||||
} else if (roleId <= 20) {
|
||||
model.put("deptVary", -1);
|
||||
model.put("deptList", new ArrayList<>());
|
||||
model.put("projectList", projectRepository.findByDeptId(admin.getDeptId()));
|
||||
model.put("showSalary", -1);
|
||||
} else if (selfProjects != null) {
|
||||
model.put("deptVary", -1);
|
||||
model.put("deptList", new ArrayList<>());
|
||||
model.put("projectList", selfProjects);
|
||||
model.put("showSalary", -1);
|
||||
} else {
|
||||
keywords = setDate(keywords);
|
||||
model.put("keywords",keywords);
|
||||
ConcurrentHashMap<String, String> searchInfo = getSearchInfo(keywords,model);
|
||||
if (searchInfo.containsKey("time")) {
|
||||
String time = searchInfo.get("time");
|
||||
if (time.length() == 7) {
|
||||
String individualTime = time.substring(0, 4) + "年" + time.substring(5, 7) + "月";
|
||||
model.put("individualTime", individualTime);
|
||||
}
|
||||
}
|
||||
model.put("pager",humanCostService.individual(searchInfo, admin.getId(), pageNumber, pageSize));
|
||||
return "admin/human_cost_individual";
|
||||
}
|
||||
keywords = setDate(keywords);
|
||||
model.put("keywords",keywords);
|
||||
ConcurrentHashMap<String, String> searchInfo = getSearchInfo(keywords,model);
|
||||
Page<ProjectUserTime> project = humanCostService.project(searchInfo, admin, pageNumber, pageSize);
|
||||
List<ProjectUserTime> staff = humanCostService.staff(searchInfo, admin);
|
||||
Map<String, BigDecimal> map = humanCostService.map(searchInfo, admin, pageNumber, pageSize);
|
||||
model.put("pager", project);
|
||||
model.put("staff", staff);
|
||||
model.put("map", map);
|
||||
return "admin/human_cost_list";
|
||||
}
|
||||
|
||||
private String setDate(String keywords) {
|
||||
if (keywords == null || keywords.length() == 0) {
|
||||
Date date = new Date();
|
||||
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM");
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
|
||||
date = calendar.getTime();
|
||||
String accDate = sf.format(date);
|
||||
keywords = "{time: '" + accDate + "'}";
|
||||
}
|
||||
return keywords;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出
|
||||
*/
|
||||
@RequestMapping("/export")
|
||||
public void export(@RequestParam(value = KEYWORDS,required = false) String keywords,
|
||||
HttpServletResponse response) throws Exception{
|
||||
Admin admin = getAdmin();
|
||||
Map<String, String> searchInfo = getSearchInfo(keywords);
|
||||
downloadHeader(response , Utils.generateExcelName("人力成本表"));
|
||||
Page<ProjectUserTime> project = humanCostService.project((ConcurrentHashMap<String, String>) searchInfo, admin, 1, 5000);
|
||||
List<ProjectUserTime> staff = humanCostService.staff((ConcurrentHashMap<String, String>) searchInfo, admin);
|
||||
Map<String, BigDecimal> map = humanCostService.map((ConcurrentHashMap<String, String>) searchInfo, admin, 1, 5000);
|
||||
String[] headers = humanCostService.getHeaders(staff);
|
||||
String[] columns = humanCostService.getColumns(project.getList());
|
||||
ExportUtils.exportHumanCost(headers, columns, staff, project.getList(),
|
||||
response.getOutputStream() , map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载导入模板
|
||||
*/
|
||||
@RequestMapping("/template")
|
||||
public void importTemplate(HttpServletResponse response) throws IOException {
|
||||
String[] headers = new String[]{"项目名称", "人员1", "人员2"};
|
||||
String[] columns = new String[]{""};
|
||||
downloadHeader(response , Utils.generateExcelName("人力成本导入模板"));
|
||||
ExportUtils exportUtils = new ExportUtils(headers);
|
||||
List<String> data = new ArrayList<>();
|
||||
data.add("成本");
|
||||
data.add("项目1");
|
||||
data.add("项目2");
|
||||
exportUtils.exportTemplate(columns , data, "yyyy-MM-dd HH:mm:ss" , 1);
|
||||
exportUtils.write(response.getOutputStream());
|
||||
}
|
||||
|
||||
@RequestMapping("/batchImport")
|
||||
@ResponseBody
|
||||
public String batchImport(MultipartFile file) {
|
||||
try {
|
||||
String date = "2021-11";
|
||||
Map<String, String> title = new HashMap<>();
|
||||
Collection<Map> maps = ExcelUtil.importHumanCost(Map.class, file.getInputStream(),
|
||||
title,0);
|
||||
return JSON.toJSONString(humanCostService.check(maps, title, date));
|
||||
} catch (OfficeXmlFileException | EncryptedDocumentException | InvalidFormatException e) {
|
||||
logger.error("", e);
|
||||
return JSON.toJSONString(ResponseMsg.buildFailedMsg("格式错误,请上传excel 2003/2007格式文件"));
|
||||
} catch (Exception e) {
|
||||
return JSON.toJSONString(ResponseMsg.buildFailedMsg("导入数据失败,请联系管理员"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,19 @@
|
|||
package cn.palmte.work.model;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface ProjectRepository extends JpaRepository<Project,Integer> {
|
||||
|
||||
@Query(value = "select * from project where name = ?1", nativeQuery = true)
|
||||
Project findByProjectName(String projectName);
|
||||
|
||||
@Query(value = "select * from project where dept_id = ?1", nativeQuery = true)
|
||||
List<Project> findByDeptId(int deptId);
|
||||
|
||||
@Query(value = "select * from project where creator_id = ?1 and end_date >= ?2 and start_date <= ?2", nativeQuery = true)
|
||||
List<Project> findByCreator(int id, Date date);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
package cn.palmte.work.model;
|
||||
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Yuanping Zhang
|
||||
* @date 2021/11/1
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "project_user_time")
|
||||
public class ProjectUserTime {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@GenericGenerator(name = "persistenceGenerator", strategy = "increment")
|
||||
private int id;
|
||||
|
||||
@Column(name = "project_id")
|
||||
private int projectId;
|
||||
|
||||
@Column(name = "project_name")
|
||||
private String projectName;
|
||||
|
||||
@Column(name = "user_id")
|
||||
private int userId;
|
||||
|
||||
@Column(name = "user_salary")
|
||||
private BigDecimal userSalary;
|
||||
|
||||
@Column(name = "user_cost")
|
||||
private BigDecimal userCost;
|
||||
|
||||
@Column(name = "user_name")
|
||||
private String userName;
|
||||
|
||||
@Column(name = "time")
|
||||
private Date time;
|
||||
|
||||
@Column(name = "created_by")
|
||||
private int createdBy;
|
||||
|
||||
@Column(name = "created_time")
|
||||
private Date createdTime;
|
||||
|
||||
@Transient
|
||||
private BigDecimal costSum;
|
||||
|
||||
@Transient
|
||||
private BigDecimal salarySum;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public void setProjectId(int projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
public String getProjectName() {
|
||||
return projectName;
|
||||
}
|
||||
|
||||
public void setProjectName(String projectName) {
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
public int getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(int userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public BigDecimal getUserSalary() {
|
||||
return userSalary;
|
||||
}
|
||||
|
||||
public void setUserSalary(BigDecimal userSalary) {
|
||||
this.userSalary = userSalary;
|
||||
}
|
||||
|
||||
public BigDecimal getUserCost() {
|
||||
return userCost;
|
||||
}
|
||||
|
||||
public void setUserCost(BigDecimal userCost) {
|
||||
this.userCost = userCost;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public Date getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Date time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public int getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
public void setCreatedBy(int createdBy) {
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
|
||||
public Date getCreatedTime() {
|
||||
return createdTime;
|
||||
}
|
||||
|
||||
public void setCreatedTime(Date createdTime) {
|
||||
this.createdTime = createdTime;
|
||||
}
|
||||
|
||||
public BigDecimal getCostSum() {
|
||||
return costSum;
|
||||
}
|
||||
|
||||
public void setCostSum(BigDecimal costSum) {
|
||||
this.costSum = costSum;
|
||||
}
|
||||
|
||||
public BigDecimal getSalarySum() {
|
||||
return salarySum;
|
||||
}
|
||||
|
||||
public void setSalarySum(BigDecimal salarySum) {
|
||||
this.salarySum = salarySum;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package cn.palmte.work.model;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Yuanping Zhang
|
||||
* @date 2021/11/1
|
||||
*/
|
||||
public interface ProjectUserTimeRepository extends JpaRepository<ProjectUserTime, Integer> {
|
||||
|
||||
@Query(value = "select * from project_user_time where user_id = ? and project_id = ? and time = ? limit 1", nativeQuery = true)
|
||||
public ProjectUserTime findByUserIdAndProjectIdAndTime(int userId, int projectId, Date time);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package cn.palmte.work.model;
|
||||
|
||||
import top.jfunc.common.db.bean.Page;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author Yuanping Zhang
|
||||
* @date 2021/11/1
|
||||
*/
|
||||
public interface ProjectUserTimeRepositoryCustom {
|
||||
|
||||
Page<ProjectUserTime> project(ConcurrentHashMap<String, String> searchInfo, Admin admin, int pageNumber, int pageSize);
|
||||
|
||||
List<ProjectUserTime> staff(ConcurrentHashMap<String, String> searchInfo, Admin admin);
|
||||
|
||||
List<ProjectUserTime> list(ConcurrentHashMap<String, String> searchInfo, Admin admin, int pageNumber, int pageSize);
|
||||
|
||||
Page<ProjectUserTime> individual(ConcurrentHashMap<String, String> searchInfo, Integer id, int pageNumber, int pageSize);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package cn.palmte.work.model;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import top.jfunc.common.db.QueryHelper;
|
||||
import top.jfunc.common.db.bean.Page;
|
||||
import top.jfunc.common.db.utils.Pagination;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author Yuanping Zhang
|
||||
* @date 2021/11/1
|
||||
*/
|
||||
@Repository
|
||||
public class ProjectUserTimeRepositoryImpl implements ProjectUserTimeRepositoryCustom {
|
||||
|
||||
@Autowired
|
||||
private Pagination pagination;
|
||||
|
||||
@Override
|
||||
public Page<ProjectUserTime> project(ConcurrentHashMap<String, String> searchInfo, Admin admin, int pageNumber, int pageSize) {
|
||||
QueryHelper helper = new QueryHelper("select put.project_name, put.project_id, put.user_id, put.user_cost, sum(put.user_cost) as costSum, sum(put.user_cost * put.user_salary) as salarySum", "from project_user_time put");
|
||||
helper.leftJoin("project proj", "put.project_id = proj.id");
|
||||
helper.leftJoin("dept", "proj.dept_id = dept.id");
|
||||
helper = searchQuery(helper, searchInfo, admin);
|
||||
helper.addGroupProperty("put.project_id");
|
||||
return pagination.paginate(helper.getSql(), ProjectUserTime.class, pageNumber, pageSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectUserTime> staff(ConcurrentHashMap<String, String> searchInfo, Admin admin) {
|
||||
QueryHelper helper = new QueryHelper("select put.user_id, put.user_name, put.user_salary", "from project_user_time put");
|
||||
helper.leftJoin("project proj", "put.project_id = proj.id");
|
||||
helper.leftJoin("dept", "proj.dept_id = dept.id");
|
||||
searchQuery(helper, searchInfo, admin);
|
||||
helper.addGroupProperty("put.user_id");
|
||||
return pagination.find(helper.getSql(), ProjectUserTime.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProjectUserTime> list(ConcurrentHashMap<String, String> searchInfo, Admin admin, int pageNumber, int pageSize) {
|
||||
QueryHelper helper = new QueryHelper("select put.project_name, put.project_id, put.user_id, put.user_cost", "from project_user_time put");
|
||||
helper.leftJoin("project proj", "put.project_id = proj.id");
|
||||
helper.leftJoin("dept", "proj.dept_id = dept.id");
|
||||
searchQuery(helper, searchInfo, admin);
|
||||
return pagination.find(helper.getSql(), ProjectUserTime.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<ProjectUserTime> individual(ConcurrentHashMap<String, String> searchInfo, Integer id, int pageNumber, int pageSize) {
|
||||
QueryHelper helper = new QueryHelper("select put.*", "from project_user_time put");
|
||||
helper.addCondition("put.user_id = ?", id);
|
||||
helper.addCondition(searchInfo.containsKey("time"),"put.time = ?", searchInfo.get("time") + "-01 00:00:00");
|
||||
helper.addOrderProperty("created_time", false);
|
||||
return pagination.paginate(helper.getSql(), ProjectUserTime.class, pageNumber, pageSize);
|
||||
}
|
||||
|
||||
private QueryHelper searchQuery(QueryHelper helper, ConcurrentHashMap<String, String> searchInfo, Admin admin) {
|
||||
helper.addCondition(searchInfo.containsKey("time"),"put.time = ?", searchInfo.get("time") + "-01 00:00:00");
|
||||
helper.addCondition(searchInfo.containsKey("projectId") && !"-1".equals(searchInfo.get("projectId")), "put.project_id = ?", searchInfo.get("projectId"));
|
||||
helper.addCondition(searchInfo.containsKey("deptId") && !"-1".equals(searchInfo.get("deptId")), "dept.id = ?", searchInfo.get("deptId"));
|
||||
helper.addCondition(searchInfo.containsKey("userName"), "put.user_name like ?", "%'" + searchInfo.get("userName") + "'%");
|
||||
if (admin.getRoleId() >= 19 && admin.getRoleId() <= 20) {
|
||||
helper.addCondition("proj.dept_id = ?", admin.getDeptId());
|
||||
} else if (admin.getRoleId() > 20) {
|
||||
helper.addCondition("proj.creator_id = ?", admin.getId());
|
||||
}
|
||||
return helper;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
package cn.palmte.work.service;
|
||||
|
||||
import cn.palmte.work.bean.ResponseMsg;
|
||||
import cn.palmte.work.model.*;
|
||||
import cn.palmte.work.utils.DateKit;
|
||||
import cn.palmte.work.utils.InterfaceUtil;
|
||||
import cn.palmte.work.utils.StrKit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import top.jfunc.common.db.bean.Page;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author Yuanping Zhang
|
||||
* @date 2021/11/1
|
||||
*/
|
||||
@Service
|
||||
public class HumanCostService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(HumanCostService.class);
|
||||
|
||||
@Autowired
|
||||
private ProjectUserTimeRepositoryImpl projectUserTimeRepositoryImpl;
|
||||
|
||||
@Autowired
|
||||
private ProjectUserTimeRepository projectUserTimeRepository;
|
||||
|
||||
@Autowired
|
||||
private ProjectRepository projectRepository;
|
||||
|
||||
@Autowired
|
||||
private AdminRepository adminRepository;
|
||||
|
||||
public Page<ProjectUserTime> project(ConcurrentHashMap<String, String> searchInfo, Admin admin, int pageNumber, int pageSize) {
|
||||
Page<ProjectUserTime> list = projectUserTimeRepositoryImpl.project(searchInfo, admin, pageNumber, pageSize);
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<ProjectUserTime> staff(ConcurrentHashMap<String, String> searchInfo, Admin admin) {
|
||||
List<ProjectUserTime> list = projectUserTimeRepositoryImpl.staff(searchInfo, admin);
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<ProjectUserTime> list(ConcurrentHashMap<String, String> searchInfo, Admin admin, int pageNumber, int pageSize) {
|
||||
List<ProjectUserTime> list = projectUserTimeRepositoryImpl.list(searchInfo, admin, pageNumber, pageSize);
|
||||
return list;
|
||||
}
|
||||
|
||||
public Map<String, BigDecimal> map(ConcurrentHashMap<String, String> searchInfo, Admin admin, int pageNumber, int pageSize) {
|
||||
List<ProjectUserTime> list = projectUserTimeRepositoryImpl.list(searchInfo, admin, pageNumber, pageSize);
|
||||
Map<String, BigDecimal> map = new HashMap<>(16);
|
||||
for (ProjectUserTime put : list) {
|
||||
map.put(put.getProjectName() + put.getUserId(), put.getUserCost());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
public Page<ProjectUserTime> individual(ConcurrentHashMap<String, String> searchInfo, Integer id, int pageNumber, int pageSize) {
|
||||
Page<ProjectUserTime> list = projectUserTimeRepositoryImpl.individual(searchInfo, id, pageNumber, pageSize);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseMsg check(Collection<Map> excelMap, Map<String, String> title, String date) {
|
||||
int successCount = 0;
|
||||
int errorCount = 0;
|
||||
Admin admin;
|
||||
BigDecimal userCost;
|
||||
BigDecimal userSalary;
|
||||
List<String> errorList = new ArrayList<>();
|
||||
Set<String> projectSet = new HashSet<>();
|
||||
Map<String, BigDecimal> staffCost = new HashMap<>();
|
||||
List<ProjectUserTime> saveList = new ArrayList<>();
|
||||
|
||||
if(excelMap.size() == 0){
|
||||
ResponseMsg msg = ResponseMsg.buildFailedMsg("请填写人力成本数据!");
|
||||
msg.setData(errorList);
|
||||
return msg;
|
||||
}
|
||||
if (title.size() < excelMap.size() - 1) {
|
||||
ResponseMsg msg = ResponseMsg.buildFailedMsg("人员名单存在重复!");
|
||||
msg.setData(errorList);
|
||||
return msg;
|
||||
}
|
||||
for (Map m : excelMap) {
|
||||
try {
|
||||
Object o1 = m.get("项目名称");
|
||||
if (o1 == null || StrKit.isBlank(o1.toString())) {
|
||||
throw new Exception("项目名称不能为空");
|
||||
}
|
||||
if ("成本".equals(o1.toString())) {
|
||||
continue;
|
||||
}
|
||||
String projectName = (String)o1;
|
||||
Project project = projectRepository.findByProjectName(projectName);
|
||||
if (project == null) {
|
||||
throw new Exception(projectName + "不存在");
|
||||
} else if (project.getStatus() != 15 || project.getApproveStatusSettle() == 1 || project.getApproveStatusSettle() == 2) {
|
||||
throw new Exception(projectName + "不在项目结算的可编辑状态");
|
||||
}
|
||||
if (projectSet.contains(projectName)) {
|
||||
throw new Exception("项目名称存在重复!");
|
||||
} else {
|
||||
projectSet.add(projectName);
|
||||
}
|
||||
for (String key : title.keySet()) {
|
||||
if (key == null || StrKit.isBlank(key)) {
|
||||
throw new Exception("人员名称不能为空");
|
||||
}
|
||||
admin = adminRepository.getAdminByRealName(key);
|
||||
if (admin == null) {
|
||||
throw new Exception(key + "不存在");
|
||||
}
|
||||
|
||||
Object o2 = m.get(key);
|
||||
if (o2 == null || StrKit.isBlank(o2.toString())) {
|
||||
throw new Exception(projectName + " " + key + "的月份额不能为空");
|
||||
}
|
||||
if (o2.toString().matches("(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){1,2})?") && BigDecimal.valueOf(1).compareTo(new BigDecimal(o2.toString())) > -1 && BigDecimal.valueOf(0).compareTo(new BigDecimal(o2.toString())) < 1) {
|
||||
userCost = new BigDecimal(o2.toString());
|
||||
} else {
|
||||
throw new Exception(projectName + " " + key + "的月份额需为0到1之间最多两位小数的数字");
|
||||
}
|
||||
String o3 = title.get(key);
|
||||
if (o3 == null || StrKit.isBlank(o3)) {
|
||||
throw new Exception(projectName + " " + key + "的成本不能为空");
|
||||
}
|
||||
if (o3.matches("(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){1,2})?") && BigDecimal.valueOf(0).compareTo(new BigDecimal(o3)) < 1) {
|
||||
userSalary = new BigDecimal(o3);
|
||||
} else {
|
||||
throw new Exception(projectName + " " + key + "的成本需为大于0的最多两位小数的的数字");
|
||||
}
|
||||
ProjectUserTime put = projectUserTimeRepository.findByUserIdAndProjectIdAndTime(admin.getId(), project.getId(), DateKit.getDate(date + "-01 00:00:00", DateKit.TIME_FORMAT));
|
||||
if (put == null) {
|
||||
put = new ProjectUserTime();
|
||||
put.setCreatedBy(InterfaceUtil.getAdminId());
|
||||
put.setCreatedTime(new Date());
|
||||
put.setTime(DateKit.getDate(date, "yyyy-MM"));
|
||||
put.setProjectId(project.getId());
|
||||
put.setProjectName(project.getName());
|
||||
put.setUserName(admin.getRealName());
|
||||
put.setUserId(admin.getId());
|
||||
}
|
||||
put.setUserCost(userCost);
|
||||
put.setUserSalary(userSalary);
|
||||
|
||||
staffCost.put(key, userCost.add(staffCost.getOrDefault(key, BigDecimal.valueOf(0))));
|
||||
saveList.add(put);
|
||||
}
|
||||
|
||||
successCount++;
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
errorCount++;
|
||||
errorList.add(e.getMessage());
|
||||
}
|
||||
}
|
||||
for (String key : staffCost.keySet()) {
|
||||
try {
|
||||
if (staffCost.getOrDefault(key, BigDecimal.valueOf(0)).compareTo(BigDecimal.valueOf(1)) != 0) {
|
||||
throw new Exception(key + "的月份额总计不为1");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("", e);
|
||||
errorCount++;
|
||||
errorList.add(e.getMessage());
|
||||
}
|
||||
}
|
||||
if (errorCount == 0) {
|
||||
projectUserTimeRepository.save(saveList);
|
||||
}
|
||||
final ResponseMsg msg = ResponseMsg.buildSuccessMsg(String.format("成功:%d, 失败:%d", successCount, errorCount));
|
||||
msg.setData(errorList);
|
||||
return msg;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("0.66".matches("(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){1,2})?"));
|
||||
System.out.println("0.66".matches("(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){1,2})?"));
|
||||
}
|
||||
|
||||
public String[] getHeaders(List<ProjectUserTime> staff) {
|
||||
String[] headers = new String[staff.size() + 3];
|
||||
headers[0] = "项目名称";
|
||||
headers[1] = "人力总计";
|
||||
headers[2] = "成本总计";
|
||||
int i = 3;
|
||||
for (ProjectUserTime person : staff) {
|
||||
headers[i++] = person.getUserName();
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
public String[] getColumns(List<ProjectUserTime> project) {
|
||||
String[] columns = new String[project.size()];
|
||||
int i = 0;
|
||||
for (ProjectUserTime p : project) {
|
||||
columns[i++] = p.getProjectName();
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
}
|
|
@ -664,4 +664,89 @@ public class ExcelUtil{
|
|||
return src.replaceAll(" ", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 把Excel的数据封装成voList
|
||||
*
|
||||
* @param clazz
|
||||
* vo的Class
|
||||
* @param inputStream
|
||||
* excel输入流
|
||||
* @param arrayCount
|
||||
* 如果vo中有数组类型,那就按照index顺序,把数组应该有几个值写上.
|
||||
* @return voList
|
||||
* @throws InvalidFormatException
|
||||
* @throws EncryptedDocumentException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Collection<T> importHumanCost(Class<T> clazz, InputStream inputStream, Map<String, String> title,
|
||||
Integer... arrayCount) throws EncryptedDocumentException, InvalidFormatException {
|
||||
Workbook workBook = null;
|
||||
try{
|
||||
workBook = (Workbook) WorkbookFactory.create(inputStream);
|
||||
}
|
||||
catch(IOException e){
|
||||
LG.error(e.toString(), e);
|
||||
}
|
||||
List<T> list = new ArrayList<T>();
|
||||
Sheet sheet = workBook.getSheetAt(0);
|
||||
Iterator<Row> rowIterator = sheet.rowIterator();
|
||||
// Map<title,index>
|
||||
Map<String, Integer> titleMap = new HashMap<String, Integer>();
|
||||
|
||||
while(rowIterator.hasNext()){
|
||||
Row row = rowIterator.next();
|
||||
if(row.getRowNum() == 0){
|
||||
// 解析map用的key,就是excel标题行
|
||||
Iterator<Cell> cellIterator = row.cellIterator();
|
||||
Integer index = 0;
|
||||
while(cellIterator.hasNext()){
|
||||
String value = cellIterator.next().getStringCellValue();
|
||||
titleMap.put(value, index);
|
||||
index++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// 整行都空,就跳过
|
||||
boolean allRowIsNull = true;
|
||||
Iterator<Cell> cellIterator = row.cellIterator();
|
||||
while(cellIterator.hasNext()){
|
||||
Object cellValue = getCellValue(cellIterator.next());
|
||||
if(cellValue != null){
|
||||
allRowIsNull = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(allRowIsNull){
|
||||
LG.warn("Excel row " + row.getRowNum() + " all row value is null!");
|
||||
continue;
|
||||
}
|
||||
T t = null;
|
||||
StringBuffer log = new StringBuffer();
|
||||
if(clazz == Map.class){
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
for(String k : titleMap.keySet()){
|
||||
Integer index = titleMap.get(k);
|
||||
Cell cell = row.getCell(index);
|
||||
String value = null;
|
||||
if(cell != null){
|
||||
int cellType = row.getCell(index).getCellType();
|
||||
if(cellType == Cell.CELL_TYPE_NUMERIC){
|
||||
row.getCell(index).setCellType(Cell.CELL_TYPE_STRING);
|
||||
}
|
||||
value = row.getCell(index).getStringCellValue();
|
||||
}
|
||||
if (!"项目名称".equals(k)) {
|
||||
if (row.getRowNum() == 1) {
|
||||
title.put(k, value);
|
||||
}
|
||||
}
|
||||
map.put(k, value);
|
||||
}
|
||||
list.add((T)map);
|
||||
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package cn.palmte.work.utils.excel;
|
||||
|
||||
import cn.palmte.work.model.ProjectUserTime;
|
||||
import cn.palmte.work.utils.DateKit;
|
||||
import cn.palmte.work.utils.ObjectKit;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
|
@ -230,4 +231,101 @@ public class ExportUtils {
|
|||
}
|
||||
return exportUtils;
|
||||
}
|
||||
|
||||
/**
|
||||
* 人力成本管理导入模板专用
|
||||
*
|
||||
* @param dataset
|
||||
* 需要显示的数据集合,集合中一定要放置符合JavaBean风格的类的对象。
|
||||
* @param pattern
|
||||
* 如果有时间数据,设定输出格式。默认为"yyyy-MM-dd"
|
||||
* @param rowIndex
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void exportTemplate(String[] columns, List<?> dataset, String pattern, int rowIndex) throws IOException{
|
||||
// 遍历集合数据,产生数据行
|
||||
int index = rowIndex;
|
||||
Font font3 = workbook.createFont();
|
||||
font3.setColor(HSSFColor.HSSFColorPredefined.BLUE.getIndex());
|
||||
for(int i = 0; i < dataset.size(); i++){
|
||||
Row row = sheet.createRow(index++);
|
||||
Object data = dataset.get(i);
|
||||
for(short col = 0; col < columns.length; col++){
|
||||
Cell cell = row.createCell(col);
|
||||
cell.setCellStyle(style2);
|
||||
Object value = data;
|
||||
cell.setCellType(CellType.STRING);
|
||||
if(value == null){
|
||||
cell.setCellType(CellType.STRING);
|
||||
cell.setCellValue("");
|
||||
}else{
|
||||
cell.setCellType(CellType.STRING);
|
||||
cell.setCellValue(value.toString());
|
||||
}
|
||||
}
|
||||
if(i != 0 && i % ROW_ACCESS_WINDOW_SIZE == 0){
|
||||
((SXSSFSheet)sheet).flushRows();
|
||||
}
|
||||
}
|
||||
((SXSSFSheet)sheet).flushRows();
|
||||
}
|
||||
|
||||
/**
|
||||
* 人力成本管理导出专用
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void exportAllData(String[] columns, String[] headers, List<ProjectUserTime> staff, List<ProjectUserTime> project, Map<String, BigDecimal> map, int rowIndex) throws IOException{
|
||||
// 遍历集合数据,产生数据行
|
||||
int index = rowIndex;
|
||||
Font font3 = workbook.createFont();
|
||||
font3.setColor(HSSFColor.HSSFColorPredefined.BLUE.getIndex());
|
||||
Row row = sheet.createRow(index++);
|
||||
Cell first = row.createCell(0);
|
||||
first.setCellStyle(style2);
|
||||
first.setCellType(CellType.STRING);
|
||||
first.setCellValue(project.get(rowIndex - 1).getProjectName());
|
||||
Cell second = row.createCell(1);
|
||||
second.setCellStyle(style2);
|
||||
second.setCellType(CellType.NUMERIC);
|
||||
second.setCellValue(project.get(rowIndex - 1).getCostSum().doubleValue());
|
||||
Cell third = row.createCell(2);
|
||||
third.setCellStyle(style2);
|
||||
third.setCellType(CellType.NUMERIC);
|
||||
third.setCellValue(project.get(rowIndex - 1).getSalarySum().doubleValue());
|
||||
for(short col = 3; col < headers.length; col++){
|
||||
Cell cell = row.createCell(col);
|
||||
cell.setCellStyle(style2);
|
||||
Object value = map.getOrDefault(project.get(rowIndex - 1).getProjectName() + staff.get(col - 3).getUserId(), new BigDecimal(0));
|
||||
cell.setCellType(CellType.STRING);
|
||||
if(value == null){
|
||||
cell.setCellType(CellType.STRING);
|
||||
cell.setCellValue("");
|
||||
} else if(value instanceof BigDecimal){
|
||||
cell.setCellType(CellType.NUMERIC);
|
||||
cell.setCellValue(((BigDecimal)value).doubleValue());
|
||||
} else{
|
||||
cell.setCellType(CellType.STRING);
|
||||
cell.setCellValue(value.toString());
|
||||
}
|
||||
}
|
||||
((SXSSFSheet)sheet).flushRows();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询数据导出到Excel的工具类
|
||||
*/
|
||||
public static <T> ExportUtils exportHumanCost(String[] headers , String[] columns , List<ProjectUserTime> staff, List<ProjectUserTime> project, OutputStream outputStream , Map<String, BigDecimal> map) throws IOException{
|
||||
ExportUtils exportUtils = new ExportUtils(headers);
|
||||
int rowIndex = 1;
|
||||
while(rowIndex <= columns.length){
|
||||
exportUtils.exportAllData(columns, headers, staff, project, map, rowIndex);
|
||||
rowIndex++;
|
||||
}
|
||||
if( null!= outputStream) {
|
||||
exportUtils.write(outputStream);
|
||||
}
|
||||
return exportUtils;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#FAFAFA;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view .layui-code-ol li:first-child{padding-top:10px}.layui-code-view .layui-code-ol li:last-child{padding-bottom:10px}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 701 B |
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 299 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,170 @@
|
|||
<#assign base=request.contextPath />
|
||||
<#import "../common/defaultLayout.ftl" as defaultLayout>
|
||||
<@defaultLayout.layout>
|
||||
<link rel="stylesheet" href="../assets/css/amazeui.switch.css"/>
|
||||
<div class="admin-content">
|
||||
<div class="am-cf am-padding" style="padding:1rem 1.6rem 1.6rem 1rem;margin:0px;">
|
||||
<!-- padding:1px 2px 3px 4px;上、右、下,和左 -->
|
||||
<div class="am-fl am-cf"><strong class="am-text-primary am-text-lg">人力成本管理</strong> /
|
||||
<small>人力成本管理</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="am-g">
|
||||
<div class="am-u-sm-12">
|
||||
<form class="am-form" id="listForm" action="${base}/humanCost/list" method="POST">
|
||||
<input type="hidden" id="keywords" name="keywords" value='${keywords!""}'/>
|
||||
<table class="am-table am-table-bordered am-table-radius table-main" style="padding:0;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="am-text-middle">项目时间</th>
|
||||
<td>
|
||||
<div class="am-u-sm-10">
|
||||
<div class="am-form am-form-inline">
|
||||
<div class="am-form-group am-form-icon">
|
||||
<input type="text" id="time" autocomplete="off" value="${time!}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td colspan="2">
|
||||
<div align='right'>
|
||||
<#-- <@shiro.hasPermission name="HUMAN_QUERY">-->
|
||||
<button type="button" class="am-btn am-btn-default am-btn-sm am-text-secondary"
|
||||
id="submit-btn">搜索
|
||||
</button>
|
||||
<#-- </@shiro.hasPermission>-->
|
||||
<#-- <@shiro.hasPermission name="HUMAN_EXPORT">-->
|
||||
<button type="button" class="am-btn am-btn-default am-btn-sm am-text-secondary"
|
||||
id="submit-btn-export">导出
|
||||
</button>
|
||||
<#-- </@shiro.hasPermission>-->
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<div class="am-u-sm-12 am-u-md-12" style="padding:0 1.6rem 1.6rem 1rem;margin:0;">
|
||||
<div class="am-btn-toolbar" style="padding-left:.5rem;">
|
||||
<div class="am-btn-group am-btn-group-xs">
|
||||
<@shiro.hasPermission name="HUMAN_IMPORT">
|
||||
|
||||
</@shiro.hasPermission>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="am-g">
|
||||
<div class="am-u-sm-12">
|
||||
<div class="am-scrollable-horizontal">
|
||||
<table class="am-table am-table-striped am-table-hover table-main">
|
||||
<thead>
|
||||
<tr class="am-text-nowrap">
|
||||
<th class="table-title">项目名称</th>
|
||||
<th class="table-title">人力总计</th>
|
||||
<th class="table-title">${individualTime!}</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<#list pager.list as list>
|
||||
<tr>
|
||||
<td>${list.projectName!}</td>
|
||||
<td>${(list.userCost!0)?string("0.##")}</td>
|
||||
<td>${(list.userCost!0)?string("0.##")}</td>
|
||||
</tr>
|
||||
</#list>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="am-cf">
|
||||
<!-- 分页 -->
|
||||
<#if (pager.list)?exists && (pager.list?size>0) >
|
||||
<div class="am-fr">
|
||||
<#include "../common/common_pager.ftl">
|
||||
</div>
|
||||
<#else>
|
||||
<div class="am-kai" align="center">
|
||||
<h3>没有找到任何记录!</h3>
|
||||
</div>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<footer class="admin-content-footer">
|
||||
<hr>
|
||||
</footer>
|
||||
</div>
|
||||
</@defaultLayout.layout>
|
||||
<script src="${base}/layui/layui.js"></script>
|
||||
<script src="../assets/js/amazeui.switch.js"></script>
|
||||
<script type="text/javascript">
|
||||
layui.use('laydate', function(){
|
||||
var laydate = layui.laydate;
|
||||
|
||||
laydate.render({
|
||||
elem: '#time',
|
||||
type: 'month',
|
||||
btns: ['confirm'],
|
||||
trigger: 'click',
|
||||
ready: function(date){
|
||||
console.log(date);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(function () {
|
||||
|
||||
$("#submit-btn").on("click", function () {
|
||||
$("#pageNumber").val(1);
|
||||
setKeywords();
|
||||
$("#listForm").attr("action","${base}/humanCost/list");
|
||||
$("#listForm").submit();
|
||||
});
|
||||
|
||||
$("#submit-btn-export").on("click", function () {
|
||||
setKeywords();
|
||||
$("#listForm").attr("action","${base}/humanCost/export");
|
||||
$("#listForm").submit();
|
||||
});
|
||||
|
||||
|
||||
function setKeywords() {
|
||||
var keywordsObj = {};
|
||||
if ($("#time").val())
|
||||
keywordsObj.time = $("#time").val();
|
||||
var keywords = "";
|
||||
if (!$.isEmptyObject(keywordsObj)) {
|
||||
keywords = JSON.stringify(keywordsObj);
|
||||
}
|
||||
console.log("keywords = " + keywords);
|
||||
|
||||
$("#keywords").val(keywords);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,318 @@
|
|||
<#assign base=request.contextPath />
|
||||
<#import "../common/defaultLayout.ftl" as defaultLayout>
|
||||
<@defaultLayout.layout>
|
||||
<link rel="stylesheet" href="../assets/css/amazeui.switch.css"/>
|
||||
<div class="admin-content">
|
||||
<div class="am-cf am-padding" style="padding:1rem 1.6rem 1.6rem 1rem;margin:0px;">
|
||||
<!-- padding:1px 2px 3px 4px;上、右、下,和左 -->
|
||||
<div class="am-fl am-cf"><strong class="am-text-primary am-text-lg">人力成本管理</strong> /
|
||||
<small>人力成本管理</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="am-g">
|
||||
<div class="am-u-sm-12">
|
||||
<form class="am-form" id="listForm" action="${base}/humanCost/list" method="POST">
|
||||
<input type="hidden" id="keywords" name="keywords" value='${keywords!""}'/>
|
||||
<table class="am-table am-table-bordered am-table-radius table-main" style="padding:0;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="am-text-middle">项目名称</th>
|
||||
<td>
|
||||
<div class="am-u-sm-10">
|
||||
<select data-am-selected id="projectId" name="projectId">
|
||||
<option value="-1">全部</option>
|
||||
<#list projectList as project>
|
||||
<option value=${project.id!} <#if projectId! =="${project.id}" >
|
||||
selected
|
||||
</#if>>${project.name!}</option>
|
||||
</#list>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<th class="am-text-middle">姓名</th>
|
||||
<td colspan="4">
|
||||
<div class="am-u-sm-10">
|
||||
<input type="text" id="userName" class="am-form-field am-input-sm"
|
||||
value="${userName!}"/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<#if deptVary gt 0>
|
||||
<tr>
|
||||
<th class="am-text-middle">一级部门</th>
|
||||
<td>
|
||||
<div class="am-u-sm-10">
|
||||
<select data-am-selected id="deptId" name="deptId">
|
||||
<option value="-1">全部</option>
|
||||
<#list deptList as dept>
|
||||
<option value=${dept.id!} <#if deptId! =="${dept.id}" >
|
||||
selected
|
||||
</#if>>${dept.name!}</option>
|
||||
</#list>
|
||||
</select>
|
||||
</div>
|
||||
</td>
|
||||
<th class="am-text-middle">项目时间</th>
|
||||
<td>
|
||||
<div class="am-u-sm-10">
|
||||
<div class="am-form am-form-inline">
|
||||
<div class="am-form-group am-form-icon">
|
||||
<input type="text" id="time" autocomplete="off" value="${time!}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<div align='right'>
|
||||
<#-- <@shiro.hasPermission name="HUMAN_COST_QUERY">-->
|
||||
<button type="button" class="am-btn am-btn-default am-btn-sm am-text-secondary"
|
||||
id="submit-btn">搜索
|
||||
</button>
|
||||
<#-- </@shiro.hasPermission>-->
|
||||
<#-- <@shiro.hasPermission name="HUMAN_COST_QUERY">-->
|
||||
<button type="button" class="am-btn am-btn-default am-btn-sm am-text-secondary"
|
||||
id="submit-btn-export">导出
|
||||
</button>
|
||||
<#-- </@shiro.hasPermission>-->
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<#else>
|
||||
<tr>
|
||||
<th class="am-text-middle">项目时间</th>
|
||||
<td>
|
||||
<div class="am-u-sm-10">
|
||||
<div class="am-form am-form-inline">
|
||||
<div class="am-form-group am-form-icon">
|
||||
<input type="text" id="time" autocomplete="off" value="${time!}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="4">
|
||||
<div align='right'>
|
||||
<#-- <@shiro.hasPermission name="HUMAN_COST_QUERY">-->
|
||||
<button type="button" class="am-btn am-btn-default am-btn-sm am-text-secondary"
|
||||
id="submit-btn">搜索
|
||||
</button>
|
||||
<#-- </@shiro.hasPermission>-->
|
||||
<#-- <@shiro.hasPermission name="HUMAN_COST_QUERY">-->
|
||||
<button type="button" class="am-btn am-btn-default am-btn-sm am-text-secondary"
|
||||
id="submit-btn-export">导出
|
||||
</button>
|
||||
<#-- </@shiro.hasPermission>-->
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</#if>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<div class="am-u-sm-12 am-u-md-12" style="padding:0 1.6rem 1.6rem 1rem;margin:0;">
|
||||
<div class="am-btn-toolbar" style="padding-left:.5rem;">
|
||||
<div class="am-btn-group am-btn-group-xs">
|
||||
<#-- <@shiro.hasPermission name="HUMAN_COST_IMPORT">-->
|
||||
<div class="am-btn-group am-btn-group-xs am-form-file">
|
||||
<button type="button" id="importAccount" class="am-btn am-btn-default"><span
|
||||
class="am-icon-archive"></span> 批量导入
|
||||
</button>
|
||||
<input id="doc-form-file" type="file" name="file"
|
||||
onChange="ajaxUploadFile('doc-form-file','${base}/humanCost/batchImport')"
|
||||
multiple>
|
||||
</div>
|
||||
<button type="button" id="importTemplate" class="am-btn am-btn-default" >
|
||||
<span class="am-icon-arrow-circle-down"></span> 导入模板
|
||||
</button>
|
||||
<#-- </@shiro.hasPermission>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="am-g">
|
||||
<div class="am-u-sm-12">
|
||||
<div class="am-scrollable-horizontal">
|
||||
<table class="am-table am-table-striped am-table-hover table-main">
|
||||
<thead>
|
||||
<tr class="am-text-nowrap">
|
||||
<th class="table-title">项目名称</th>
|
||||
<th class="table-title">人力总计</th>
|
||||
<th class="table-title">成本总计</th>
|
||||
<#if (staff)?exists>
|
||||
<#list staff as person>
|
||||
<th class="table-title">${person.userName!}
|
||||
<#if showSalary gt 0>(成本:${(person.userSalary!0)?string("0.##")}元)</#if></th>
|
||||
</#list>
|
||||
</#if>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<#if (pager.list)?exists>
|
||||
<#list pager.list as list>
|
||||
<tr>
|
||||
<td>${list.projectName!}</td>
|
||||
<td>${(list.costSum!0)?string("0.##")}</td>
|
||||
<td>${(list.salarySum!0)?string("0.##")}</td>
|
||||
<#if (staff)?exists>
|
||||
<#list staff as person>
|
||||
<td>${((map[list.projectName + person.userId])!0)?string("0.##")}</td>
|
||||
</#list>
|
||||
</#if>
|
||||
</tr>
|
||||
</#list>
|
||||
</#if>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="am-cf">
|
||||
<!-- 分页 -->
|
||||
<#if (pager.list)?exists && (pager.list?size>0) >
|
||||
<div class="am-fr">
|
||||
<#include "../common/common_pager.ftl">
|
||||
</div>
|
||||
<#else>
|
||||
<div class="am-kai" align="center">
|
||||
<h3>没有找到任何记录!</h3>
|
||||
</div>
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<footer class="admin-content-footer">
|
||||
<hr>
|
||||
</footer>
|
||||
</div>
|
||||
</@defaultLayout.layout>
|
||||
<script src="../assets/js/jquery.ajaxfileupload.js"></script>
|
||||
<script src="../assets/js/amazeui.switch.js"></script>
|
||||
<script src="${base}/layui/layui.js"></script>
|
||||
<script type="text/javascript">
|
||||
layui.use('laydate', function(){
|
||||
var laydate = layui.laydate;
|
||||
|
||||
laydate.render({
|
||||
elem: '#time',
|
||||
type: 'month',
|
||||
btns: ['confirm'],
|
||||
trigger: 'click',
|
||||
ready: function(date){
|
||||
console.log(date);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
*导入模板下载
|
||||
*/
|
||||
$("#importTemplate").on('click', function(event) {
|
||||
location.href = "${base}/humanCost/template";
|
||||
});
|
||||
|
||||
function ajaxUploadFile(id, url) {
|
||||
// if ($('#modal')) {
|
||||
// $('#modal').modal('open');
|
||||
// $('#span-' + id).html(" 数据正在导入,请等待");
|
||||
// }
|
||||
$("#exportFaildButton").hide();
|
||||
$.ajaxFileUpload({
|
||||
url: url,
|
||||
secureuri: false,
|
||||
fileElementId: id,// file标签的id
|
||||
dataType: 'json',// 返回数据的类型
|
||||
success: function (data, status) {
|
||||
console.log("--------success---------" + data)
|
||||
// if($('#modal')){
|
||||
// $('#modal').modal('close');
|
||||
// $('#span-'+id).html("导入完成");
|
||||
// }
|
||||
if(data.status ==0) {
|
||||
var list = data.data;
|
||||
var content = '';
|
||||
$.each(list, function (i, r) {
|
||||
content += (i+1) + '、' + r + '<br>';
|
||||
});
|
||||
console.log('---> ' + content);
|
||||
parent.layer.open({
|
||||
title: '导入结果:' ,
|
||||
content: data.msg + '<br><br>' + content
|
||||
});
|
||||
}else{
|
||||
parent.layer.msg(data.msg);
|
||||
}
|
||||
|
||||
window.location.reload();
|
||||
$("#" + id).val("");
|
||||
},
|
||||
error: function (data, status, e) {
|
||||
console.log("--------error---------" + data)
|
||||
alert("-----------------" + data);
|
||||
if ($('#modal')) {
|
||||
$('#modal').modal('close');
|
||||
}
|
||||
alert(e);
|
||||
$("#" + id).val("");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$(function () {
|
||||
|
||||
$("#submit-btn").on("click", function () {
|
||||
$("#pageNumber").val(1);
|
||||
setKeywords();
|
||||
$("#listForm").attr("action","${base}/humanCost/list");
|
||||
$("#listForm").submit();
|
||||
});
|
||||
|
||||
$("#submit-btn-export").on("click", function () {
|
||||
setKeywords();
|
||||
$("#listForm").attr("action","${base}/humanCost/export");
|
||||
$("#listForm").submit();
|
||||
});
|
||||
|
||||
|
||||
function setKeywords() {
|
||||
var keywordsObj = {};
|
||||
if ($("#projectId").val())
|
||||
keywordsObj.projectId = $("#projectId").val();
|
||||
if ($("#userName").val())
|
||||
keywordsObj.userName = $("#userName").val();
|
||||
if ($("#deptId").val())
|
||||
keywordsObj.deptId = $("#deptId").val();
|
||||
if ($("#time").val())
|
||||
keywordsObj.time = $("#time").val();
|
||||
var keywords = "";
|
||||
if (!$.isEmptyObject(keywordsObj)) {
|
||||
keywords = JSON.stringify(keywordsObj);
|
||||
}
|
||||
console.log("keywords = " + keywords);
|
||||
|
||||
$("#keywords").val(keywords);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue