浏览代码

将发表信息展示在项目明细列表中
修改发表申请选择上级公司报错问题
添加外出申请工作流模块内容

user5 5 年之前
父节点
当前提交
7a25443363
共有 25 个文件被更改,包括 2756 次插入22 次删除
  1. 3 0
      src/main/java/com/jeeplus/modules/projectcontentinfo/dao/ProjectReportDataDao.java
  2. 11 0
      src/main/java/com/jeeplus/modules/projectrecord/entity/ProjectRecords.java
  3. 11 8
      src/main/java/com/jeeplus/modules/projectrecord/service/ProjectRecordsService.java
  4. 12 0
      src/main/java/com/jeeplus/modules/workgooutapply/dao/WorkGoOutDao.java
  5. 163 0
      src/main/java/com/jeeplus/modules/workgooutapply/entity/WorkGoOutInfo.java
  6. 655 0
      src/main/java/com/jeeplus/modules/workgooutapply/service/WorkGoOutService.java
  7. 380 0
      src/main/java/com/jeeplus/modules/workgooutapply/web/WorkGoOutController.java
  8. 20 1
      src/main/java/com/jeeplus/modules/workinvoice/entity/WorkInvoice.java
  9. 10 2
      src/main/java/com/jeeplus/modules/workinvoice/web/WorkInvoiceController.java
  10. 25 0
      src/main/java/com/jeeplus/modules/workprojectnotify/web/WorkProjectNotifyController.java
  11. 19 0
      src/main/resources/mappings/modules/projectcontentinfo/ProjectReportDataDao.xml
  12. 189 0
      src/main/resources/mappings/modules/workgooutapply/WorkGoOutDao.xml
  13. 78 0
      src/main/webapp/webpage/modules/projectrecord/projectRecordsView.jsp
  14. 219 0
      src/main/webapp/webpage/modules/workgoout/workGoOutAudit.jsp
  15. 231 0
      src/main/webapp/webpage/modules/workgoout/workGoOutForm.jsp
  16. 319 0
      src/main/webapp/webpage/modules/workgoout/workGoOutList.jsp
  17. 239 0
      src/main/webapp/webpage/modules/workgoout/workGoOutModifyApply.jsp
  18. 15 0
      src/main/webapp/webpage/modules/workgoout/workGoOutTask.jsp
  19. 146 0
      src/main/webapp/webpage/modules/workgoout/workGoOutView.jsp
  20. 2 2
      src/main/webapp/webpage/modules/workinvoice/workInvoiceForm.jsp
  21. 2 2
      src/main/webapp/webpage/modules/workinvoice/workInvoiceView.jsp
  22. 1 1
      src/main/webapp/webpage/modules/workleave/workLeaveAudit.jsp
  23. 2 2
      src/main/webapp/webpage/modules/workleave/workLeaveForm.jsp
  24. 2 2
      src/main/webapp/webpage/modules/workleave/workLeaveModify.jsp
  25. 2 2
      src/main/webapp/webpage/modules/workleave/workLeaveView.jsp

+ 3 - 0
src/main/java/com/jeeplus/modules/projectcontentinfo/dao/ProjectReportDataDao.java

@@ -6,6 +6,7 @@ package com.jeeplus.modules.projectcontentinfo.dao;
 import com.jeeplus.common.persistence.CrudDao;
 import com.jeeplus.common.persistence.annotation.MyBatisDao;
 import com.jeeplus.modules.projectcontentinfo.entity.ProjectReportData;
+import com.jeeplus.modules.workinvoice.entity.WorkInvoice;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -70,5 +71,7 @@ public interface ProjectReportDataDao extends CrudDao<ProjectReportData> {
 
     List<ProjectReportData> findByProjectId(String projectId);
 
+    List<WorkInvoice> getInvoiceByProjectId(String projectId);
+
     ProjectReportData findByNum(String number);
 }

+ 11 - 0
src/main/java/com/jeeplus/modules/projectrecord/entity/ProjectRecords.java

@@ -14,6 +14,7 @@ import com.jeeplus.modules.sys.entity.User;
 import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
 import com.jeeplus.modules.workclientinfo.entity.WorkClientLinkman;
 import com.jeeplus.modules.workcontractinfo.entity.WorkContractInfo;
+import com.jeeplus.modules.workinvoice.entity.WorkInvoice;
 import org.hibernate.validator.constraints.NotBlank;
 
 import javax.validation.constraints.NotNull;
@@ -77,6 +78,8 @@ public class ProjectRecords extends ActEntity<ProjectRecords> {
 
 	private List<User> projectMembers;  //项目组成员
 
+	private List<WorkInvoice> workInvoices;   //发票信息
+
 	private String leaderNameStr;
 	private String leaderIds;
 	private String memberNameStr;
@@ -569,4 +572,12 @@ public class ProjectRecords extends ActEntity<ProjectRecords> {
 	public void setProjectReportData(List<ProjectReportData> projectReportData) {
 		this.projectReportData = projectReportData;
 	}
+
+	public List<WorkInvoice> getWorkInvoices() {
+		return workInvoices;
+	}
+
+	public void setWorkInvoices(List<WorkInvoice> workInvoices) {
+		this.workInvoices = workInvoices;
+	}
 }

+ 11 - 8
src/main/java/com/jeeplus/modules/projectrecord/service/ProjectRecordsService.java

@@ -10,7 +10,6 @@ import com.jeeplus.common.utils.Collections3;
 import com.jeeplus.common.utils.DateUtils;
 import com.jeeplus.common.utils.IdGen;
 import com.jeeplus.common.utils.MenuStatusEnum;
-import com.jeeplus.common.websocket.onchat.ChatServerPool;
 import com.jeeplus.modules.act.entity.Act;
 import com.jeeplus.modules.act.service.ActTaskService;
 import com.jeeplus.modules.act.utils.ProcessDefCache;
@@ -20,13 +19,12 @@ import com.jeeplus.modules.projectcontentinfo.entity.ProjectReportData;
 import com.jeeplus.modules.projectcontentinfo.entity.Projectcontentinfo;
 import com.jeeplus.modules.projectrecord.dao.ProjectClientLinkmanDao;
 import com.jeeplus.modules.projectrecord.dao.ProjectRecordsDao;
+import com.jeeplus.modules.projectrecord.dao.WorkProjectUserDao;
 import com.jeeplus.modules.projectrecord.entity.ProjectRecords;
 import com.jeeplus.modules.projectrecord.enums.ProjectStatusEnum;
 import com.jeeplus.modules.serialnum.service.SerialNumTplService;
-import com.jeeplus.modules.sys.entity.Dict;
 import com.jeeplus.modules.sys.entity.Office;
 import com.jeeplus.modules.sys.entity.User;
-import com.jeeplus.modules.sys.service.DictService;
 import com.jeeplus.modules.sys.service.OfficeService;
 import com.jeeplus.modules.sys.utils.DictUtils;
 import com.jeeplus.modules.sys.utils.UserUtils;
@@ -38,7 +36,6 @@ import com.jeeplus.modules.workactivity.service.WorkActivityProcessService;
 import com.jeeplus.modules.workactivitymenu.entity.WorkActivityMenu;
 import com.jeeplus.modules.workactivitymenu.service.WorkActivityMenuService;
 import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
-import com.jeeplus.modules.workclientinfo.dao.WorkClientInfoDao;
 import com.jeeplus.modules.workclientinfo.dao.WorkClientLinkmanDao;
 import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
 import com.jeeplus.modules.workclientinfo.entity.WorkClientInfo;
@@ -47,11 +44,10 @@ import com.jeeplus.modules.workclientinfo.service.WorkClientInfoService;
 import com.jeeplus.modules.workcontractinfo.dao.WorkContractInfoDao;
 import com.jeeplus.modules.workcontractinfo.entity.WorkContractInfo;
 import com.jeeplus.modules.workcontractinfo.service.WorkContractInfoService;
+import com.jeeplus.modules.workinvoice.entity.WorkInvoice;
 import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
 import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
 import com.jeeplus.modules.workprojectnotify.util.UtilNotify;
-import com.jeeplus.modules.projectrecord.dao.WorkProjectUserDao;
-import org.activiti.engine.ActivitiObjectNotFoundException;
 import org.activiti.engine.HistoryService;
 import org.activiti.engine.IdentityService;
 import org.activiti.engine.RuntimeService;
@@ -59,8 +55,6 @@ import org.activiti.engine.history.HistoricTaskInstance;
 import org.activiti.engine.history.HistoricTaskInstanceQuery;
 import org.activiti.engine.runtime.ProcessInstance;
 import org.apache.commons.lang3.StringUtils;
-import org.java_websocket.WebSocket;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeArtExtension;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -1009,6 +1003,13 @@ public class ProjectRecordsService extends CrudService<ProjectRecordsDao, Projec
 
 	}
 
+	public void queryInvoiceData(ProjectRecords projectRecords){
+		String projectId = projectRecords.getId();
+		List<WorkInvoice> invoiceByProjectId = projectReportDataDao.getInvoiceByProjectId(projectId);
+		projectRecords.setWorkInvoices(invoiceByProjectId);
+
+	}
+
 	private void saveAttachments(ProjectRecords projectRecords) {
 		if (projectRecords.getWorkAttachments()!=null && !projectRecords.getWorkAttachments().isEmpty()) {
 			//保存附件信息
@@ -1071,6 +1072,8 @@ public class ProjectRecordsService extends CrudService<ProjectRecordsDao, Projec
         this.queryWorkAttachment(projectRecords);
         //设置报告
         this.queryReportData(projectRecords);
+        //获取项目发票信息
+        this.queryInvoiceData(projectRecords);
     }
 
     public Page<ProjectRecords> findPageDetail(Page<ProjectRecords> page, ProjectRecords projectRecords) {

+ 12 - 0
src/main/java/com/jeeplus/modules/workgooutapply/dao/WorkGoOutDao.java

@@ -0,0 +1,12 @@
+package com.jeeplus.modules.workgooutapply.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.workgooutapply.entity.WorkGoOutInfo;
+
+@MyBatisDao
+public interface WorkGoOutDao extends CrudDao<WorkGoOutInfo> {
+    void updateProcessIdAndStatus(WorkGoOutInfo workGoOutInfo);
+
+    int queryCount(WorkGoOutInfo workGoOutInfo);
+}

+ 163 - 0
src/main/java/com/jeeplus/modules/workgooutapply/entity/WorkGoOutInfo.java

@@ -0,0 +1,163 @@
+package com.jeeplus.modules.workgooutapply.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.google.common.collect.Lists;
+import com.jeeplus.common.persistence.ActEntity;
+import com.jeeplus.common.utils.excel.annotation.ExcelField;
+import com.jeeplus.modules.projectrecord.entity.ProjectRecords;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+
+import java.util.Date;
+import java.util.List;
+
+public class WorkGoOutInfo extends ActEntity<WorkGoOutInfo> {
+    private static final long serialVersionUID = 1L;
+    public static final String ATTACHMENT_TYPE = "92";
+    public static final String SERIAL_BIZCODE = "92";  //编号模板value值
+    private Office office;		// 部门ID
+    private Office company;		// 公司ID
+    private String docType;		// 文档类型
+    private String num;		// 申请编号
+    private User submiter;		// 申请人
+    private Date submitDate;		// 申请日期
+    private Integer state;		// 审批状态
+    private String processInstanceId;		// 流程ID
+    private List<WorkClientAttachment> workAttachments = Lists.newArrayList();
+    private Date beginDate;
+    private Date endDate;
+    private String home;
+    private ProjectRecords project;
+    private String ext;
+
+
+    public String getExt() {
+        return ext;
+    }
+
+    public void setExt(String ext) {
+        this.ext = ext;
+    }
+
+    public ProjectRecords getProject() {
+        return project;
+    }
+
+    public void setProject(ProjectRecords project) {
+        this.project = project;
+    }
+
+    public WorkGoOutInfo() {
+        super();
+    }
+
+    public WorkGoOutInfo(String id){
+        super(id);
+    }
+
+    @ExcelField(title="部门ID", align=2, sort=7)
+    public Office getOffice() {
+        return office;
+    }
+
+    public void setOffice(Office office) {
+        this.office = office;
+    }
+
+    @ExcelField(title="公司ID", align=2, sort=8)
+    public Office getCompany() {
+        return company;
+    }
+
+    public void setCompany(Office company) {
+        this.company = company;
+    }
+
+    @ExcelField(title="文档类型", dictType="", align=2, sort=9)
+    public String getDocType() {
+        return docType;
+    }
+
+    public void setDocType(String docType) {
+        this.docType = docType;
+    }
+
+    @ExcelField(title="申请编号", align=2, sort=10)
+    public String getNum() {
+        return num;
+    }
+
+    public void setNum(String num) {
+        this.num = num;
+    }
+
+    public User getSubmiter() {
+        return submiter;
+    }
+
+    public void setSubmiter(User submiter) {
+        this.submiter = submiter;
+    }
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ExcelField(title="申请日期", align=2, sort=13)
+    public Date getSubmitDate() {
+        return submitDate;
+    }
+
+    public void setSubmitDate(Date submitDate) {
+        this.submitDate = submitDate;
+    }
+
+    @ExcelField(title="审批状态", align=2, sort=15)
+    public Integer getState() {
+        return state;
+    }
+
+    public void setState(Integer state) {
+        this.state = state;
+    }
+
+    @ExcelField(title="流程ID", align=2, sort=16)
+    public String getProcessInstanceId() {
+        return processInstanceId;
+    }
+
+    public void setProcessInstanceId(String processInstanceId) {
+        this.processInstanceId = processInstanceId;
+    }
+
+    public List<WorkClientAttachment> getWorkAttachments() {
+        return workAttachments;
+    }
+
+    public void setWorkAttachments(List<WorkClientAttachment> workAttachments) {
+        this.workAttachments = workAttachments;
+    }
+
+    public Date getBeginDate() {
+        return beginDate;
+    }
+
+    public void setBeginDate(Date beginDate) {
+        this.beginDate = beginDate;
+    }
+
+    public Date getEndDate() {
+        return endDate;
+    }
+
+    public void setEndDate(Date endDate) {
+        this.endDate = endDate;
+    }
+
+    public String getHome() {
+        return home;
+    }
+
+    public void setHome(String home) {
+        this.home = home;
+    }
+
+}

+ 655 - 0
src/main/java/com/jeeplus/modules/workgooutapply/service/WorkGoOutService.java

@@ -0,0 +1,655 @@
+package com.jeeplus.modules.workgooutapply.service;
+
+import com.google.common.collect.Maps;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MenuStatusEnum;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.isignature.service.ISignatureDocumentService;
+import com.jeeplus.modules.projectrecord.enums.ProjectStatusEnum;
+import com.jeeplus.modules.serialnum.service.SerialNumTplService;
+import com.jeeplus.modules.sys.dao.UserDao;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workactivity.dao.WorkActivityProcessDao;
+import com.jeeplus.modules.workactivity.entity.Activity;
+import com.jeeplus.modules.workactivity.entity.WorkActivityProcess;
+import com.jeeplus.modules.workactivity.service.ActivityService;
+import com.jeeplus.modules.workactivity.service.WorkActivityProcessService;
+import com.jeeplus.modules.workactivitymenu.entity.WorkActivityMenu;
+import com.jeeplus.modules.workactivitymenu.service.WorkActivityMenuService;
+import com.jeeplus.modules.workclientinfo.dao.WorkClientAttachmentDao;
+import com.jeeplus.modules.workclientinfo.entity.WorkClientAttachment;
+import com.jeeplus.modules.workgooutapply.dao.WorkGoOutDao;
+import com.jeeplus.modules.workgooutapply.entity.WorkGoOutInfo;
+import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
+import com.jeeplus.modules.workprojectnotify.service.WorkProjectNotifyService;
+import com.jeeplus.modules.workprojectnotify.util.UtilNotify;
+import org.activiti.engine.HistoryService;
+import org.activiti.engine.IdentityService;
+import org.activiti.engine.RuntimeService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class WorkGoOutService extends CrudService<WorkGoOutDao, WorkGoOutInfo> {
+
+    @Autowired
+    private WorkClientAttachmentDao workClientAttachmentDao;
+    @Autowired
+    private UserDao userDao;
+    @Autowired
+    private WorkProjectNotifyService workProjectNotifyService;
+    @Autowired
+    private IdentityService identityService;
+    @Autowired
+    private ActTaskService actTaskService;
+    @Autowired
+    private WorkActivityMenuService workActivityMenuService;
+    @Autowired
+    private RuntimeService runtimeService;
+    @Autowired
+    private WorkActivityProcessService workActivityProcessService;
+    @Autowired
+    private ActivityService activityService;
+    @Autowired
+    protected HistoryService historyService;
+    @Autowired
+    private WorkActivityProcessDao workActivityProcessDao;
+    @Autowired
+    private SerialNumTplService serialNumTplService;
+    @Autowired
+    private ISignatureDocumentService signatureDocumentService;
+
+    public WorkGoOutInfo get(String id) {
+        WorkGoOutInfo workGoOutInfo = super.get(id);
+        if(workGoOutInfo!=null&&StringUtils.isNotBlank(workGoOutInfo.getId())){
+            WorkClientAttachment attchment = new WorkClientAttachment();
+            attchment.setAttachmentId(workGoOutInfo.getId());
+            workGoOutInfo.setWorkAttachments(workClientAttachmentDao.findList(attchment));
+        }
+        return workGoOutInfo;
+    }
+
+    public Page<WorkGoOutInfo> findPage(Page<WorkGoOutInfo> page, WorkGoOutInfo workGoOutInfo) {
+        workGoOutInfo.getSqlMap().put("dsf", dataScopeFilter(workGoOutInfo.getCurrentUser(), "o", "u","s", MenuStatusEnum.WORK_FIELD.getValue()));
+        workGoOutInfo.setPage(page);
+        page.setList(findList(workGoOutInfo));
+        return page;
+    }
+
+    public List<WorkGoOutInfo> findList(WorkGoOutInfo workGoOutInfo) {
+        return super.findList(workGoOutInfo);
+    }
+
+    @Transactional(readOnly = false)
+    public String saveAtamp(WorkGoOutInfo workGoOutInfo) {
+        save(workGoOutInfo);
+        return this.startAudit(workGoOutInfo,workGoOutInfo.getProcessInstanceId());
+    }
+
+    @Transactional(readOnly = false)
+    public void save(WorkGoOutInfo workGoOutInfo) {
+        long t1 = System.currentTimeMillis();
+        preSave(workGoOutInfo);
+        super.save(workGoOutInfo);
+        this.saveAttachments(workGoOutInfo);
+        logger.info("保存项目外出申请耗时:{}ms",System.currentTimeMillis()-t1);
+    }
+
+    private void preSave(WorkGoOutInfo workGoOutInfo) {
+
+        if(workGoOutInfo.getOffice()==null|| StringUtils.isBlank(workGoOutInfo.getOffice().getId())){
+            workGoOutInfo.setOffice(UserUtils.getSelectOffice());
+        }
+        if(workGoOutInfo.getCompany()==null||StringUtils.isBlank(workGoOutInfo.getCompany().getId())){
+            workGoOutInfo.setCompany(UserUtils.getSelectCompany());
+        }
+        if (StringUtils.isBlank(workGoOutInfo.getNum())){
+            String serialNum = serialNumTplService.genSerialNum(UserUtils.getUser().getCompany(), WorkGoOutInfo.SERIAL_BIZCODE);
+            workGoOutInfo.setNum(serialNum);
+        }
+    }
+
+    private void saveAttachments(WorkGoOutInfo workGoOutInfo) {
+        for (WorkClientAttachment workClientAttachment : workGoOutInfo.getWorkAttachments()) {
+            if (workClientAttachment.getId() == null) {
+                continue;
+            }
+            if (WorkClientAttachment.DEL_FLAG_NORMAL.equals(workClientAttachment.getDelFlag())) {
+                workClientAttachment.setAttachmentId(workGoOutInfo.getId());
+                workClientAttachment.setAttachmentFlag(WorkGoOutInfo.ATTACHMENT_TYPE);
+                workClientAttachment.setAttachmentUser(UserUtils.getUser().getId());
+                if (StringUtils.isBlank(workClientAttachment.getId()) || "null".equals(workClientAttachment.getId())) {
+                    workClientAttachment.preInsert();
+                    workClientAttachmentDao.insert(workClientAttachment);
+                    signatureDocumentService.createIsignature(workClientAttachment.getUrl(),workClientAttachment.getAttachmentName(),workClientAttachment.getId(),workGoOutInfo.getNum());
+                } else {
+                    workClientAttachment.preUpdate();
+                    workClientAttachmentDao.update(workClientAttachment);
+                }
+            } else {
+                workClientAttachmentDao.delete(workClientAttachment);
+            }
+        }
+    }
+
+    /**
+     * 启动审批流程
+     */
+    private String startAudit(WorkGoOutInfo workGoOutInfo, String processInstanceId){
+        long t1 = System.currentTimeMillis();
+        Map<String, Object> variables = new HashMap<String, Object>();
+        identityService.setAuthenticatedUserId(workGoOutInfo.getCurrentUser().getId());
+        String contentStr = "申请编号:"+workGoOutInfo.getNum()+",申请日期:"+ DateUtils.formatDate(workGoOutInfo.getCreateDate());
+        String titleStr = "申请人:"+ workGoOutInfo.getSubmiter().getName();
+
+        String businessKey = workGoOutInfo.getId();
+        Office office = UserUtils.getSelectOffice();
+        WorkActivityMenu workActivityMenu = workActivityMenuService.findByParentAndOffice("ggh3125fwef194582bdda9abcew750904", office);
+        // 启动流程
+        String processType = workActivityMenu.getProcessType();
+        StringBuffer buffer = new StringBuffer();
+        Activity activity = new Activity();
+        WorkProjectNotify workProjectNotify = UtilNotify
+                .saveNotify(workGoOutInfo.getId(),
+                        null,
+                        workGoOutInfo.getCompany().getId(),
+                        titleStr,
+                        contentStr,
+                        "92",
+                        "0",
+                        "待审批",
+                        ""
+                );
+
+        List<User> users = new ArrayList<>();
+        List<User> gzrList = null;
+        List<User> bmzrList = UserUtils.getByRoleActivityEnname("bmzr",2,office.getId(),"11",workGoOutInfo.getCreateBy());
+        List<User> fgldList = UserUtils.getByRoleActivityEnname("fzjl",3,office.getId(),"11",workGoOutInfo.getCreateBy());
+        if (StringUtils.isNotBlank(workActivityMenu.getId())) {
+            workProjectNotify.setNotifyRole("");
+            workActivityMenu = workActivityMenuService.get(workActivityMenu.getId());
+            List<Activity> activities = workActivityMenu.getActivities();
+            for (Activity a : activities) {
+                String encount = a.getEncount();
+                String enlist = a.getEnlist();
+                if (a.getRole()!=null && StringUtils.isNotBlank(a.getRole().getEnname())){
+                    List enusers = UserUtils.getByRoleActivityEnnames(a.getRole().getEnname(),office.getId(),"11",workGoOutInfo.getCreateBy());
+                    if (enusers.size()==0){
+                        workGoOutInfo.setState(ProjectStatusEnum.TSTORE.getValue());
+                        this.updateStateById(workGoOutInfo);
+                        return "流程审批人不能为空,角色"+a.getRole().getName()+"下无用户,请联系管理员!";
+                    }
+                    variables.put(enlist, enusers);
+                    variables.put(encount, enusers.size());
+                }
+                if (a.getDelFlag().equals("0") && a.getCount() == 1) {
+                    activity = a;
+                }
+            }
+            buffer.append(activity.getRole().getEnname());
+            if (activity != null && StringUtils.isNotBlank(activity.getId())) {
+                //角色审批
+                if (StringUtils.isNotBlank(activity.getRole().getEnname())) {
+                    users = UserUtils.getByRoleActivityEnnames(activity.getRole().getEnname(),office.getId(),"11",workGoOutInfo.getCreateBy());
+                }
+                //人员审批
+                if (StringUtils.isNotBlank(activity.getUser().getId())) {
+                    users.add(activity.getUser());
+                }
+            }
+            workProjectNotify.setId("");
+        } else {
+            if (bmzrList.size()==0){
+                workGoOutInfo.setState(ProjectStatusEnum.TSTORE.getValue());
+                this.updateStateById(workGoOutInfo);
+                return "流程审批人不能为空,部门负责人下无用户,请联系管理员!";
+            }
+            variables.put("bmzrList", bmzrList);
+            variables.put("bmzrCount",bmzrList.size());
+            processType = "notadministrativeAtamp";
+            users.addAll(bmzrList);
+        }
+        List<String> userIds = new ArrayList<>(users.size());
+        for (User u : users){
+            userIds.add(u.getId());
+            workProjectNotify.setUser(u);
+            workProjectNotify.setId("");
+            workProjectNotify.setNotifyRole("部门负责人审批");
+            workProjectNotifyService.save(workProjectNotify);
+            Map<String,Object> extras = new HashMap<>();
+            extras.put("type","7002");
+            extras.put("procDefKey","92");
+            extras.put("id",workProjectNotify.getId());
+            UserUtils.pushInfoToApp(titleStr, contentStr,extras,u.getId());
+        }
+        long t2 = System.currentTimeMillis();
+        UserUtils.pushIm(userIds,contentStr);
+        logger.info("项目签章推送消息耗时:{}ms",System.currentTimeMillis()-t2);
+
+        variables.put("busId", businessKey);
+        variables.put("type", processType);
+        variables.put("title", "审批单:" + workGoOutInfo.getNum());//设置标题;
+
+        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processType, businessKey, variables);
+        if (org.apache.commons.lang3.StringUtils.isNotBlank(processInstanceId)) {
+            workActivityProcessService.updateProcessInstanceId(processInstance.getId(),processInstanceId);
+            workActivityProcessService.deleteProcessInstanceId(processInstanceId);
+            workActivityProcessService.deleteProcessIdAuditUsers(processInstanceId);
+        }
+        List<Activity> list = workActivityMenu.getActivities();
+        if (list != null && list.size() != 0) {
+            workActivityProcessService.saveList(list, processInstance.getId());
+        } else {
+            WorkActivityProcess workActivityProcess = new WorkActivityProcess();
+            workActivityProcess.setProcessKey(processType);
+            workActivityProcess.setCount(1);
+            workActivityProcess.setProcessInstanceId(processInstance.getId());
+            workActivityProcess.setIsApproval("0");
+            workActivityProcessService.save(workActivityProcess);
+            workActivityProcess.setCount(2);
+            workActivityProcess.setId("");
+            workActivityProcessService.save(workActivityProcess);
+            workActivityProcessService.insertAuditsByType(bmzrList,processInstance.getId(),1,1);
+            workActivityProcessService.insertAuditsByType(fgldList,processInstance.getId(),2,0);
+        }
+        workGoOutInfo.setProcessInstanceId(processInstance.getId());
+        workGoOutInfo.setState(ProjectStatusEnum.IN_APRL.getValue());
+        dao.updateProcessIdAndStatus(workGoOutInfo);
+        logger.info("启动项目外出审批流程耗时:{}ms",System.currentTimeMillis()-t1);
+        return "";
+    }
+
+
+    private void updateStateById(WorkGoOutInfo workGoOutInfo) {
+        dao.updateProcessIdAndStatus(workGoOutInfo);
+    }
+
+    /**
+     * 外出审核流程
+     */
+    @Transactional(readOnly = false)
+    public String goOutProjectSave(WorkGoOutInfo workGoOutInfo,List<User> auditUsers) {
+        String str = "申请编号:"+workGoOutInfo.getNum()+",申请人:"+workGoOutInfo.getSubmiter().getName() +",申请日期:"+ DateUtils.formatDate(workGoOutInfo.getCreateDate());
+        String title = "申请人:"+ workGoOutInfo.getSubmiter().getName();
+        // 对不同环节的业务逻辑进行操作
+        String taskDefKey = workGoOutInfo.getAct().getTaskDefKey();
+        if (!"modifyApply".equals(taskDefKey) && !taskDefKey.contains("audit")) {
+            actTaskService.claim(workGoOutInfo.getAct().getTaskId(), UserUtils.getUser().getId());
+        }else {
+            workGoOutInfo.getAct().setFlag("yes");
+            this.saveAttachments(workGoOutInfo);
+        }
+        String comment = "";
+        if (ProjectStatusEnum.REJECTED.getValue() == workGoOutInfo.getState()){
+            comment = ("yes".equals(workGoOutInfo.getAct().getFlag())?"[重新申请] ":"[已撤销] ");
+        }else {
+            comment = ("yes".equals(workGoOutInfo.getAct().getFlag())?"[同意] ":"[驳回] ")+ workGoOutInfo.getAct().getComment();
+        }
+        //yes 的时候状态为审核通过 否则为未通过
+        //1 审核中 2 未通过
+        workGoOutInfo.setState(("yes".equals(workGoOutInfo.getAct().getFlag()) ? ProjectStatusEnum.IN_APRL.getValue() : ProjectStatusEnum.REJECTED.getValue()));
+        Map<String, Object> vars = Maps.newHashMap();
+        //业务逻辑对应的条件表达式
+        String exp = "";
+        String taskCount = "";
+        String notifyRole = "";
+        int key = 0;
+        String enname = "";
+        List<Activity> activitieList = activityService.getByProcessInstanceId(workGoOutInfo.getProcessInstanceId());
+        WorkActivityMenu workActivityMenu = new WorkActivityMenu();
+        if (activitieList != null && activitieList.size() != 0) {
+            workActivityMenu.setProcessType(activitieList.get(0).getProcessKey());
+            workActivityMenu.setActivities(activitieList);
+        }
+
+        WorkActivityProcess workActivityProcess = new WorkActivityProcess();
+        WorkActivityProcess selectProcess = new WorkActivityProcess();
+        selectProcess.setProcessInstanceId(workGoOutInfo.getProcessInstanceId());
+        List<WorkActivityProcess> workActivityProcesses = workActivityProcessService.findList(selectProcess);
+        List<Activity> activities = workActivityMenu.getActivities();
+        if (StringUtils.isNotBlank(workActivityMenu.getProcessType()) && (!workActivityMenu.getProcessType().equals("notadministrativeAtamp"))) {
+            key = 1;
+            for (int i = 0; i < workActivityProcesses.size(); i++) {
+                WorkActivityProcess activityProcess = workActivityProcesses.get(i);
+                if (taskDefKey.equals(activityProcess.getActivityTask()) && !taskDefKey.equals("modifyApply")) {
+                    taskCount = activityProcess.getCount()+"";
+                    workActivityProcess = activityProcess;
+                    if (!workActivityProcess.getIsApproval().equals("0")) {
+                        workActivityProcess.setId("");
+                    }
+                    exp = "pass";
+                    if (!"yes".equals(workGoOutInfo.getAct().getFlag())) {
+                        notifyRole = "调整外出请求信息";
+                        workGoOutInfo.setState(ProjectStatusEnum.REJECTED.getValue());
+                        workActivityProcess.setIsApproval("2");
+                        String returnBack = "-1";
+                        for (Activity activity : activities) {
+                            if (activity.getCount() == activityProcess.getCount()) {
+                                notifyRole = activity.getName();
+                                returnBack = activity.getReturnBack();
+                                break;
+                            }
+                        }
+                        if (returnBack.equals("0")) {
+                            workActivityProcess.setId("");
+                        }
+
+                    } else {
+                        workActivityProcess.setIsApproval("1");
+                    }
+                }else if(taskDefKey.equals("modifyApply")){
+                    taskCount = "0";
+                    exp = "pass";
+                    workActivityProcess.setId("");
+                    workActivityProcess.setCount(0);
+                    if (!"yes".equals(workGoOutInfo.getAct().getFlag())) {
+                        workGoOutInfo.setState(ProjectStatusEnum.RECALL.getValue());
+                        workActivityProcess.setIsApproval("2");
+                    } else {
+                        workActivityProcess.setIsApproval("1");
+                    }
+                    break;
+                }
+            }
+        } else {
+            workActivityMenu.setProcessType("notadministrativeAtamp");
+            for (int i = 0; i < workActivityProcesses.size(); i++) {
+                WorkActivityProcess activityProcess = workActivityProcesses.get(i);
+                String count = activityProcess.getCount() + "";
+                workActivityProcess = activityProcess;
+                if (!workActivityProcess.getIsApproval().equals("0")) {
+                    workActivityProcess.setId("");
+                }
+                // 审核环节
+                if ("bmzr".equals(taskDefKey) && count.contains("1")) {
+                    taskCount = "1";
+                    exp = "pass";
+                    if ("yes".equals(workGoOutInfo.getAct().getFlag())) {
+                        workActivityProcessService.insertAuditsByType(auditUsers, workGoOutInfo.getProcessInstanceId(), 2, 1);
+
+                        notifyRole = "副总经理审核";
+                        workActivityProcess.setIsApproval("1");
+                        enname = "fgld";
+                        vars.put("fgldCount", auditUsers.size());
+                        vars.put("fgldList", auditUsers);
+                        vars.put("pass",true);
+                    } else {
+                        notifyRole = "调整申请";
+                        workActivityProcess.setIsApproval("2");
+                        vars.put("pass",false);
+                    }
+                    break;
+                } else if ("fgld".equals(taskDefKey) && count.contains("2")) {
+                    taskCount = "2";
+                    exp = "pass";
+                    if ("yes".equals(workGoOutInfo.getAct().getFlag())) {
+                        notifyRole = "审批通过";
+                        workActivityProcess.setIsApproval("1");
+                        vars.put("pass",true);
+                    } else {
+                        notifyRole = "调整外出请求信息";
+                        workActivityProcess.setIsApproval("2");
+                        vars.put("pass",false);
+                    }
+                    break;
+                } else if ("modifyApply".equals(taskDefKey) && count.contains("0")) {
+                    notifyRole = "部门负责人审批";
+                    taskCount = "0";
+                    exp = "pass";
+                    workActivityProcess.setCount(0);
+                    enname = "bmzr";
+                    if (!"yes".equals(workGoOutInfo.getAct().getFlag())) {
+                        workGoOutInfo.setState(ProjectStatusEnum.RECALL.getValue());
+                    }
+                    break;
+                } else if ("apply_end".equals(taskDefKey)) {
+                }
+            }
+        }
+        // 设置意见
+        workGoOutInfo.getAct().setComment(("yes".equals(workGoOutInfo.getAct().getFlag()) ? "[同意] " : "[驳回] ") + workGoOutInfo.getAct().getComment());
+        workGoOutInfo.preUpdate();
+        // 提交流程任务
+        vars.put(exp, "yes".equals(workGoOutInfo.getAct().getFlag()) ? true : false);
+        vars.put("passs", true);
+        workActivityProcessService.updateProcess(workActivityProcess,workActivityMenu,key,taskCount, workGoOutInfo.getProcessInstanceId(),taskDefKey,"modifyApply", workGoOutInfo.getAct().getFlag(),comment, activities);
+        // 提交流程任务
+        actTaskService.complete(workGoOutInfo.getAct().getTaskId(), workGoOutInfo.getAct().getProcInsId(), workGoOutInfo.getAct().getComment(), vars);
+        boolean state = actTaskService.isProcessEnd(workGoOutInfo.getAct().getProcInsId());
+        List<User> users = new ArrayList<>();
+        List<User> userList = new ArrayList<>();
+        if (!state) {
+            users.add(workGoOutInfo.getCreateBy());
+            if ("yes".equals(workGoOutInfo.getAct().getFlag())) {
+                workGoOutInfo.setState(ProjectStatusEnum.SIGNED.getValue());
+                WorkProjectNotify notify = new WorkProjectNotify();
+                notify.setNotifyId(workGoOutInfo.getId());
+                userList = workProjectNotifyService.readByNotifyId(notify);
+                workProjectNotifyService
+                        .save(UtilNotify
+                                .saveNotify(workGoOutInfo.getId(),
+                                        workGoOutInfo.getCreateBy(),
+                                        workGoOutInfo.getCompany().getId(),
+                                        title,
+                                        str,
+                                        "92",
+                                        "0",
+                                        "待通知",
+                                        notifyRole));
+
+            } else {
+                WorkProjectNotify notify = new WorkProjectNotify();
+                notify.setNotifyId(workGoOutInfo.getId());
+                userList = workProjectNotifyService.readByNotifyId(notify);
+                if (ProjectStatusEnum.RECALL.getValue() != workGoOutInfo.getState()){
+                    workGoOutInfo.setState(ProjectStatusEnum.REJECTED.getValue());
+                    workProjectNotifyService
+                            .save(UtilNotify
+                                    .saveNotify(workGoOutInfo.getId(),
+                                            workGoOutInfo.getCreateBy(),
+                                            workGoOutInfo.getCompany().getId(),
+                                            title,
+                                            str,
+                                            "92",
+                                            "0",
+                                            "待通知",
+                                            notifyRole));
+                }
+            }
+            workActivityProcessService.deleteProcessIdAuditUsers(workGoOutInfo.getProcessInstanceId());
+        } else {
+            if (StringUtils.isNotBlank(workActivityMenu.getProcessType()) && (!workActivityMenu.getProcessType().equals("notadministrativeAtamp"))) {
+                WorkProjectNotify notify = new WorkProjectNotify();
+                notify.setNotifyId(workGoOutInfo.getId());
+                userList = workProjectNotifyService.readByNotifyId(notify);
+                //users.addAll(userList);
+                WorkProjectNotify workProjectNotify = UtilNotify
+                        .saveNotify(workGoOutInfo.getId(),
+                                new User(),
+                                workGoOutInfo.getCompany().getId(),
+                                title,
+                                str,
+                                "92",
+                                "0",
+                                "待审批",
+                                notifyRole);
+                List<WorkProjectNotify> workProjectNotifys = activityService.getByFlagAndTaskDefKeyList(
+                        activities,
+                        workProjectNotify,
+                        taskDefKey,
+                        workGoOutInfo.getAct().getFlag(),
+                        taskCount,
+                        workGoOutInfo.getCreateBy(),
+                        workGoOutInfo.getOffice().getId(),
+                        "92");
+                for (WorkProjectNotify workProjectNotify1:workProjectNotifys){
+                    users.add(workProjectNotify1.getUser());
+                    workProjectNotify1.setId("");
+                    workProjectNotify1.setIsNewRecord(false);
+                    workProjectNotifyService
+                            .save(workProjectNotify1);
+                }
+
+            } else {
+                if (!"yes".equals(workGoOutInfo.getAct().getFlag())) {
+                    WorkProjectNotify notify = new WorkProjectNotify();
+                    notify.setNotifyId(workGoOutInfo.getId());
+                    userList = workProjectNotifyService.readByNotifyId(notify);
+                    //users.addAll(userList);
+                    workProjectNotifyService
+                            .save(UtilNotify
+                                    .saveNotify(workGoOutInfo.getId(),
+                                            workGoOutInfo.getCreateBy(),
+                                            workGoOutInfo.getCompany().getId(),
+                                            title,
+                                            str,
+                                            "92",
+                                            "0",
+                                            "重新申请",
+                                            notifyRole));
+                    users.add( workGoOutInfo.getCreateBy());
+                } else {
+                    if (StringUtils.isNotBlank(enname)) {
+                        WorkProjectNotify notify = new WorkProjectNotify();
+                        notify.setNotifyId(workGoOutInfo.getId());
+                        userList = workProjectNotifyService.readByNotifyId(notify);
+                        //users.addAll(userList1);
+                        WorkProjectNotify workProjectNotify = UtilNotify
+                                .saveNotify(workGoOutInfo.getId(),
+                                        new User(),
+                                        workGoOutInfo.getCompany().getId(),
+                                        title,
+                                        str,
+                                        "92",
+                                        "0",
+                                        "待审批",
+                                        notifyRole);
+                        users.addAll(auditUsers);
+                        for (User user1:auditUsers){
+                            workProjectNotify.setUser(user1);
+                            workProjectNotify.setId("");
+                            workProjectNotify.setIsNewRecord(false);
+                            workProjectNotifyService.save(workProjectNotify);
+                            Map<String,Object> extras = new HashMap<>();
+                            if(enname.contains("bmzr")||enname.contains("fgld")) {
+                                extras.put("type", "7002");
+                            }else {
+                                extras.put("type", "7001");
+                            }
+                            extras.put("procDefKey","92");
+                            extras.put("id",workProjectNotify.getId());
+                            UserUtils.pushInfoToApp(title, str,extras,user1.getId());
+                        }
+                    }else {
+                        WorkProjectNotify notify = new WorkProjectNotify();
+                        notify.setNotifyId(workGoOutInfo.getId());
+                        userList = workProjectNotifyService.readByNotifyId(notify);
+                        users.add(workGoOutInfo.getCreateBy());
+                        workProjectNotifyService
+                                .save(UtilNotify
+                                        .saveNotify(workGoOutInfo.getId(),
+                                                workGoOutInfo.getCreateBy(),
+                                                workGoOutInfo.getCompany().getId(),
+                                                title,
+                                                str,
+                                                "92",
+                                                "0",
+                                                "重新申请",
+                                                notifyRole));
+                    }
+                }
+            }
+        }
+        if (StringUtils.isNotBlank(title) && users!=null && users.size()!=0) {
+            for (User u : users) {
+                UserUtils.pushIm(u.getId(),title);
+            }
+        }
+        if (StringUtils.isNotBlank(title) && userList!=null && userList.size()!=0) {
+            for (User u : userList) {
+                UserUtils.pushMeIm(u.getId());
+            }
+        }
+        dao.update(workGoOutInfo);
+        return "保存审核意见成功!";
+    }
+
+    @Transactional(readOnly = false)
+    public void cancelProcess(WorkGoOutInfo workGoOutInfo) throws Exception {
+        WorkActivityProcess process = new WorkActivityProcess();
+        process.setProcessInstanceId(workGoOutInfo.getProcessInstanceId());
+        process.setIsApproval("0");
+        WorkActivityProcess workActivityProcess = new WorkActivityProcess();
+        workActivityProcess.setProcessInstanceId(workGoOutInfo.getProcessInstanceId());
+        List<WorkActivityProcess> processList = workActivityProcessService.findList(workActivityProcess);
+        WorkProjectNotify notify = new WorkProjectNotify();
+        notify.setNotifyId(workGoOutInfo.getId());
+        List<User> userList = workProjectNotifyService.readByNotifyId(notify);
+        if (userList!=null && userList.size()!=0) {
+            for (User u : userList) {
+                User user = UserUtils.get(u.getId());
+                UserUtils.pushIm(u.getId(),"申请人 "+user.getName() +",外出请求审批编号:"+workGoOutInfo.getNum() +" 强制撤销!");
+
+            }
+        }
+        if(processList!=null && processList.size()>0){
+            for (int i =0;i<processList.size();i++) {
+                WorkActivityProcess p = processList.get(i);
+                if(StringUtils.isNotBlank(p.getIsApproval()) && "0".equals(p.getIsApproval())){
+                    p.setIsApproval("-1");
+                    p.setDelFlag("1");
+                    workActivityProcessDao.updateDelFlagAndIsApproval(p);
+                }
+            }
+            WorkActivityProcess pro = new WorkActivityProcess();
+            pro.setId("");
+            pro.setDelFlag("0");
+            pro.preInsert();
+            pro.setRemarks("[强制撤销]");
+            pro.setProcessKey(processList.get(0).getProcessKey());
+            pro.setIsApproval("1");
+            pro.setProcessInstanceId(processList.get(0).getProcessInstanceId());
+            pro.setCount(0);
+            workActivityProcessDao.insert(pro);
+
+            //结束该流程,设为"撤销"状态月
+            WorkGoOutInfo workGoOut = new WorkGoOutInfo();
+            workGoOut.setId(workGoOutInfo.getId());
+            workGoOut.setState(ProjectStatusEnum.RECALL.getValue());
+            workGoOut.setProcessInstanceId(workGoOutInfo.getProcessInstanceId());
+            workGoOut.preUpdate();
+            this.updateStateById(workGoOut);
+            actTaskService.endProcessInstance(workGoOutInfo.getProcessInstanceId(), "外出申请-撤回");
+        }
+    }
+
+    @Transactional(readOnly = false)
+    public void delete(WorkGoOutInfo workGoOutInfo) {
+        super.delete(workGoOutInfo);
+        if(workGoOutInfo.getWorkAttachments()!=null&&workGoOutInfo.getWorkAttachments().size()>0){
+            for (WorkClientAttachment workClientAttachment : workGoOutInfo.getWorkAttachments()) {
+                workClientAttachmentDao.delete(workClientAttachment);
+            }
+        }
+        WorkProjectNotify notify = new WorkProjectNotify();
+        notify.setNotifyId(workGoOutInfo.getId());
+        List<User> users = workProjectNotifyService.readByNotifyId(notify);
+        if (users!=null && users.size()!=0){
+            for (User user:users){
+                UserUtils.pushMeIm(user.getId());
+            }
+        }
+    }
+}

+ 380 - 0
src/main/java/com/jeeplus/modules/workgooutapply/web/WorkGoOutController.java

@@ -0,0 +1,380 @@
+package com.jeeplus.modules.workgooutapply.web;
+
+import com.google.common.collect.Lists;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.DateUtils;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ExportExcel;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.act.entity.Act;
+import com.jeeplus.modules.act.service.ActTaskService;
+import com.jeeplus.modules.projectrecord.enums.ProjectStatusEnum;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import com.jeeplus.modules.workgooutapply.entity.WorkGoOutInfo;
+import com.jeeplus.modules.workgooutapply.service.WorkGoOutService;
+import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.Task;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.ConstraintViolationException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+
+@Controller
+@RequestMapping("${adminPath}/workgoout/workGoOut")
+public class WorkGoOutController  extends BaseController {
+
+    @Autowired
+    private HttpServletRequest request;
+
+    @Autowired
+    private ActTaskService actTaskService;
+
+    @Autowired
+    WorkGoOutService workGoOutService ;
+
+    @ModelAttribute
+    public WorkGoOutInfo get(@RequestParam(required=false) String id) {
+        WorkGoOutInfo entity = null;
+        if (StringUtils.isNotBlank(id)){
+            entity = workGoOutService.get(id);
+        }
+        if (entity == null){
+            entity = new WorkGoOutInfo();
+        }
+        return entity;
+    }
+
+    /**
+     * 外出申请列表页面
+     * @param workGoOutInfo
+     * @param request
+     * @param response
+     * @param model
+     * @return
+     */
+    @RequiresPermissions("workgoout:workGoOut:list")
+    @RequestMapping(value = {"list", ""})
+    public String list(WorkGoOutInfo workGoOutInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
+        Page<WorkGoOutInfo> page = workGoOutService.findPage(new Page<WorkGoOutInfo>(request, response), workGoOutInfo);
+        model.addAttribute("page", page);
+        return "modules/workgoout/workGoOutList";
+    }
+
+    /**
+     * 查看,增加,编辑外出申请表单页面
+     * @param workGoOutInfo
+     * @param model
+     * @return
+     */
+    @RequiresPermissions(value={"workgoout:workGoOut:view"},logical= Logical.OR)
+    @RequestMapping(value = "view")
+    public String view(WorkGoOutInfo workGoOutInfo, Model model) {
+        model.addAttribute("workGoOut", workGoOutInfo);
+        return "modules/workgoout/workGoOutView";
+    }
+
+    /**
+     * 查看,增加,编辑项目盖章表单页面
+     */
+    @RequiresPermissions(value={"workgoout:workGoOut:view","workgoout:workGoOut:add","workgoout:workGoOut:edit"},logical=Logical.OR)
+    @RequestMapping(value = "form")
+    public String form(WorkGoOutInfo workGoOutInfo, Model model) {
+        if(workGoOutInfo.getSubmitDate()==null){
+            workGoOutInfo.setSubmitDate(new Date());
+        }
+        if(workGoOutInfo.getSubmiter()==null){
+            workGoOutInfo.setSubmiter(UserUtils.getUser());
+        }
+        if(workGoOutInfo.getOffice()==null||StringUtils.isBlank(workGoOutInfo.getOffice().getId())){
+            workGoOutInfo.setOffice(UserUtils.getSelectOffice());
+        }
+        String view = "workGoOutForm";
+        String tabId = request.getParameter("tabId");
+        model.addAttribute("workGoOut", workGoOutInfo);
+        if("3".equals(tabId)){
+            ProcessInstance processInstance = actTaskService.getProcIns(workGoOutInfo.getProcessInstanceId());
+            if (processInstance!=null) {
+                Task taskInfok = actTaskService.getCurrentTaskInfo(processInstance);
+                Act act = new Act();
+                act.setTaskId(taskInfok.getId());
+                act.setTaskName(taskInfok.getName());
+                act.setTaskDefKey(taskInfok.getTaskDefinitionKey());
+                act.setProcDefId(taskInfok.getProcessDefinitionId());
+                act.setProcInsId(taskInfok.getProcessInstanceId());
+                act.setTask(taskInfok);
+                workGoOutInfo.setAct(act);
+                view = "workGoOutModifyApply";
+            }
+        }
+        return "modules/workgoout/"+view;
+    }
+
+    /**
+     * 暂存外出申请
+     * @param workGoOutInfo
+     * @param model
+     * @param redirectAttributes
+     * @return
+     * @throws Exception
+     */
+    @RequiresPermissions(value={"workgoout:workGoOut:add","workgoout:workGoOut:edit"},logical=Logical.OR)
+    @RequestMapping(value = "tstore")
+    public String tStore(WorkGoOutInfo workGoOutInfo, Model model, RedirectAttributes redirectAttributes) throws Exception{
+        if (!beanValidator(model, workGoOutInfo)){
+            return form(workGoOutInfo, model);
+        }
+        try {
+            workGoOutInfo.setState(ProjectStatusEnum.TSTORE.getValue());
+            if (!workGoOutInfo.getIsNewRecord()) {//编辑表单保存
+                WorkGoOutInfo t = workGoOutService.get(workGoOutInfo.getId());//从数据库取出记录的值
+                MyBeanUtils.copyBeanNotNull2Bean(workGoOutInfo, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+                workGoOutService.save(t);//保存
+            } else {//新增表单保存
+                workGoOutService.save(workGoOutInfo);//保存
+            }
+            addMessage(redirectAttributes, "暂存项目外出成功");
+        }catch (Exception e){
+            logger.error("暂存项目外出异常:",e);
+            addMessage(redirectAttributes, "暂存项目外出异常:"+e.getMessage());
+        }
+        return "redirect:"+Global.getAdminPath()+"/workgoout/workGoOut/?repage";
+    }
+
+    /**
+     * 保存外出申请
+     * @param workGoOutInfo
+     * @param model
+     * @param redirectAttributes
+     * @return
+     * @throws Exception
+     */
+    @RequiresPermissions(value={"workgoout:workGoOut:add","workgoout:workGoOut:edit"},logical=Logical.OR)
+    @RequestMapping(value = "save")
+    public String save(WorkGoOutInfo workGoOutInfo, Model model, RedirectAttributes redirectAttributes) throws Exception{
+        if (!beanValidator(model, workGoOutInfo)){
+            return form(workGoOutInfo, model);
+        }
+        workGoOutInfo.setState(ProjectStatusEnum.IN_APRL.getValue());
+        String str = "";
+        if(!workGoOutInfo.getIsNewRecord()){//编辑表单保存
+            WorkGoOutInfo t = workGoOutService.get(workGoOutInfo.getId());//从数据库取出记录的值
+            MyBeanUtils.copyBeanNotNull2Bean(workGoOutInfo, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+            str = workGoOutService.saveAtamp(t);//保存
+        }else{//新增表单保存
+            str = workGoOutService.saveAtamp(workGoOutInfo);//保存
+        }
+        if (StringUtils.isNotBlank(str)){
+            addMessage(redirectAttributes, "保存项目外出失败:"+str);
+        }else {
+            addMessage(redirectAttributes, "保存项目外出成功");
+        }
+        return "redirect:"+ Global.getAdminPath()+"/workgoout/workGoOut/?repage";
+    }
+
+    /**
+     * 工单执行(完成任务)
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = "saveAudit")
+    public String saveAudit(WorkGoOutInfo workGoOutInfo, Model model,
+                            RedirectAttributes redirectAttributes) {
+        // 对不同环节的业务逻辑进行操作
+        String taskDefKey = workGoOutInfo.getAct().getTaskDefKey();
+        List<User> users = null;
+        if ("bmzr".equals(taskDefKey)){
+            users = UserUtils.getByProssType(workGoOutInfo.getProcessInstanceId(),2);
+            if (users==null )
+                users = UserUtils.getByRoleActivityEnname("fzjl",3,UserUtils.getSelectOffice().getId(),"11",workGoOutInfo.getCreateBy());
+        }else  if ("fgld".equals(taskDefKey)){
+            users = UserUtils.getByProssType(workGoOutInfo.getProcessInstanceId(),3);
+            if (users==null )
+                users = UserUtils.getByRoleActivityEnname("fzjl",3,UserUtils.getSelectOffice().getId(),"11",workGoOutInfo.getCreateBy());
+        }else if ("modifyApply".equals(taskDefKey)){
+            users = UserUtils.getByProssType(workGoOutInfo.getProcessInstanceId(),1);
+        }
+        String flag = workGoOutInfo.getAct().getFlag();
+        if ("yes".equals(flag) && (users==null || users.size()==0)){
+            addMessage(redirectAttributes, "审批失败,审批人为空,请联系管理员!");
+        }else {
+            String str = workGoOutService.goOutProjectSave(workGoOutInfo,users);
+            addMessage(redirectAttributes, str);
+        }
+        if (StringUtils.isNotBlank(workGoOutInfo.getHome()) && "home".equals(workGoOutInfo.getHome())){
+            return "redirect:" + Global.getAdminPath() + "/home/?repage";
+        }else {
+            return "redirect:" + Global.getAdminPath() + "/workgoout/workGoOut/?repage";
+        }
+    }
+
+    /**
+     * 审核
+     * @param act
+     * @param workGoOutInfo
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = "audit")
+    public String workContractInfoAudit(Act act, WorkGoOutInfo workGoOutInfo, Model model) {
+
+        if (act.getProcInsId() != null) {
+            if (actTaskService.getProcIns(act.getProcInsId()) != null) {
+                act.setProcIns(actTaskService.getProcIns(act.getProcInsId()));
+            } else {
+                act.setFinishedProcIns(actTaskService.getFinishedProcIns(act.getProcInsId()));
+            }
+        }
+        if (act != null && StringUtils.isNotBlank(act.getTaskId())) {
+            workGoOutInfo.setAct(act);
+            model.addAttribute("processInstanceId", workGoOutInfo.getProcessInstanceId());
+        }
+        model.addAttribute("workGoOut", workGoOutInfo);
+        return "modules/workgoout/workGoOutAudit";
+    }
+
+    /**
+     * 流程展示请求
+     * @param workGoOutInfo
+     * @param model
+     * @param request
+     * @return
+     */
+    @RequestMapping(value = "getProcess")
+    public String getProcess(WorkGoOutInfo workGoOutInfo, Model model, HttpServletRequest request){
+        model.addAttribute("processInstanceId", workGoOutInfo.getProcessInstanceId());
+        return "modules/workgoout/workGoOutTask";
+    }
+
+
+    /**
+     * 撤回请求
+     * @param request
+     * @param redirectAttributes
+     * @return
+     */
+    @RequiresPermissions(value={"workgoout:workGoOut:edit"},logical=Logical.OR)
+    @RequestMapping(value = "revoke")
+    public String revoke(HttpServletRequest request, RedirectAttributes redirectAttributes) {
+        HashMap<String, String> requestMap = findRequestMap(request);
+        String processInstanceId = requestMap.get("processInstanceId");
+        String id = requestMap.get("id");
+        try {
+            WorkGoOutInfo workGoOutInfo = workGoOutService.get(id);
+            if(5==workGoOutInfo.getState()){
+                addMessage(redirectAttributes, "外出申请已审批通过,无法撤回");
+                return "redirect:"+Global.getAdminPath()+"/workgoout/workGoOut/?repage";
+            }
+            workGoOutService.cancelProcess(workGoOutInfo);
+            addMessage(redirectAttributes, "撤回该外出求情审批成功");
+        }catch (Exception e){
+            logger.info(e.getMessage());
+            addMessage(redirectAttributes, "撤回该外出请求审批失败");
+        }
+        return "redirect:" + Global.getAdminPath() + "/workgoout/workGoOut/?repage";
+    }
+
+    /**
+     * 删除项目盖章
+     */
+    @RequiresPermissions("workgoout:workGoOut:del")
+    @RequestMapping(value = "delete")
+    public String delete(WorkGoOutInfo workGoOutInfo, RedirectAttributes redirectAttributes) {
+        if(5==workGoOutInfo.getState()|| 2==workGoOutInfo.getState()){
+            if(5==workGoOutInfo.getState()){
+                addMessage(redirectAttributes, "项目外出申请已审批通过,无法删除");
+                return "redirect:"+Global.getAdminPath()+"/workgoout/workGoOut/?repage";
+            }else{
+                addMessage(redirectAttributes, "项目外出申请正在审核中,无法删除");
+                return "redirect:"+Global.getAdminPath()+"/workgoout/workGoOut/?repage";
+            }
+        }
+        workGoOutService.delete(workGoOutInfo);
+        addMessage(redirectAttributes, "删除项目外出申请成功");
+        return "redirect:"+Global.getAdminPath()+"/workgoout/workGoOut/?repage";
+    }
+
+    /**
+     * 导出excel文件
+     */
+    @RequiresPermissions("workgoout:workGoOut:export")
+    @RequestMapping(value = "export", method= RequestMethod.POST)
+    public String exportFile(WorkGoOutInfo workGoOutInfo, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        try {
+            String fileName = "项目外出"+ DateUtils.getDate("yyyyMMddHHmmss")+".xlsx";
+            Page<WorkGoOutInfo> page = workGoOutService.findPage(new Page<WorkGoOutInfo>(request, response, -1), workGoOutInfo);
+            new ExportExcel("项目外出", WorkGoOutInfo.class).setDataList(page.getList()).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导出项目外出记录失败!失败信息:"+e.getMessage());
+        }
+        return "redirect:"+Global.getAdminPath()+"/workgoout/workGoOut/?repage";
+    }
+
+    /**
+     * 导入Excel数据
+
+     */
+    @RequiresPermissions("workgoout:workGoOut:import")
+    @RequestMapping(value = "import", method=RequestMethod.POST)
+    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes) {
+        try {
+            int successNum = 0;
+            int failureNum = 0;
+            StringBuilder failureMsg = new StringBuilder();
+            ImportExcel ei = new ImportExcel(file, 1, 0);
+            List<WorkGoOutInfo> list = ei.getDataList(WorkGoOutInfo.class);
+            for (WorkGoOutInfo workGoOut : list){
+                try{
+                    workGoOutService.save(workGoOut);
+                    successNum++;
+                }catch(ConstraintViolationException ex){
+                    failureNum++;
+                }catch (Exception ex) {
+                    failureNum++;
+                }
+            }
+            if (failureNum>0){
+                failureMsg.insert(0, ",失败 "+failureNum+" 条项目盖章记录。");
+            }
+            addMessage(redirectAttributes, "已成功导入 "+successNum+" 条项目外出记录"+failureMsg);
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导入项目外出失败!失败信息:"+e.getMessage());
+        }
+        return "redirect:"+Global.getAdminPath()+"/workgoout/workGoOut/?repage";
+    }
+
+    /**
+     * 下载导入项目盖章数据模板
+     */
+    @RequiresPermissions("workgoout:workGoOut:import")
+    @RequestMapping(value = "import/template")
+    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes) {
+        try {
+            String fileName = "项目外出数据导入模板.xlsx";
+            List<WorkGoOutInfo> list = Lists.newArrayList();
+            new ExportExcel("项目外出数据", WorkGoOutInfo.class, 1).setDataList(list).write(response, fileName).dispose();
+            return null;
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "导入模板下载失败!失败信息:"+e.getMessage());
+        }
+        return "redirect:"+Global.getAdminPath()+"/workgoout/workGoOut/?repage";
+    }
+}

+ 20 - 1
src/main/java/com/jeeplus/modules/workinvoice/entity/WorkInvoice.java

@@ -12,7 +12,6 @@ import com.jeeplus.modules.sys.entity.Office;
 import com.jeeplus.modules.sys.entity.User;
 import com.jeeplus.modules.workclientinfo.entity.WorkClientInfo;
 import com.jeeplus.modules.workinvoicedetail.entity.WorkInvoiceDetail;
-import com.jeeplus.modules.workproject.entity.WorkProject;
 import org.activiti.engine.history.HistoricProcessInstance;
 import org.activiti.engine.repository.ProcessDefinition;
 import org.activiti.engine.runtime.ProcessInstance;
@@ -67,6 +66,26 @@ public class WorkInvoice extends ActEntity<WorkInvoice> {
 	private Date beginContractDate;		// 开始
 	private Date endContractDate;		// 结束
 	private List<WorkInvoiceDetail> workAccountList = Lists.newArrayList();//发票明细
+
+	private String workAccountNumber;    //发票号
+	private Double taxMoney;      //开票金额
+
+	public String getWorkAccountNumber() {
+		return workAccountNumber;
+	}
+
+	public void setWorkAccountNumber(String workAccountNumber) {
+		this.workAccountNumber = workAccountNumber;
+	}
+
+	public Double getTaxMoney() {
+		return taxMoney;
+	}
+
+	public void setTaxMoney(Double taxMoney) {
+		this.taxMoney = taxMoney;
+	}
+
 	public String getOfficeId() {
 		return officeId;
 	}

+ 10 - 2
src/main/java/com/jeeplus/modules/workinvoice/web/WorkInvoiceController.java

@@ -41,7 +41,6 @@ import com.jeeplus.modules.workinvoice.entity.WorkInvoice;
 import com.jeeplus.modules.workinvoice.service.WorkInvoiceService;
 import com.jeeplus.modules.workinvoicealter.entity.WorkInvoiceAlter;
 import com.jeeplus.modules.workinvoicealter.service.WorkInvoiceAlterService;
-import com.jeeplus.modules.workinvoicedetail.dao.WorkInvoiceDetailDao;
 import com.jeeplus.modules.workinvoicedetail.service.WorkInvoiceDetailService;
 import com.jeeplus.modules.workproject.service.WorkProjectService;
 import com.jeeplus.modules.workprojectnotify.entity.WorkProjectNotify;
@@ -242,6 +241,13 @@ public class WorkInvoiceController extends BaseController {
 		return "modules/workinvoice/" + view;
 	}
 
+	@RequestMapping("form1")
+	public String form1(String id,Model model){
+		WorkInvoice workInvoice = workInvoiceService.get(id);
+		model.addAttribute("workInvoice", workInvoice);
+		return "modules/workinvoice/workInvoiceView";
+	}
+
 	/**
 	 * 保存开票管理
 	 */
@@ -271,6 +277,7 @@ public class WorkInvoiceController extends BaseController {
 			workInvoice.setProject(workProject);
 			workInvoice.setCompanyId(UserUtils.getSelectCompany().getId());
 			workInvoice.setOfficeId(UserUtils.getSelectOffice().getId());
+			workInvoice.setExt("0");
 			String str = "";
 			//1总公司0分公司
 			if("1".equals(workInvoice.getExt())){
@@ -759,7 +766,8 @@ public class WorkInvoiceController extends BaseController {
 	 * @return
 	 */
 	@RequestMapping(value = "getProcessOne")
-	public String getProcessOne(WorkInvoice workInvoice,Model model) {
+	public String getProcessOne(String id,Model model) {
+		WorkInvoice workInvoice = workInvoiceService.get(id);
 		model.addAttribute("processInstanceId", workInvoice.getProcessInstanceId());
 		return "modules/workinvoice/workInvoiceTask";
 	}

+ 25 - 0
src/main/java/com/jeeplus/modules/workprojectnotify/web/WorkProjectNotifyController.java

@@ -116,6 +116,8 @@ import com.jeeplus.modules.workfullsupervisorsheet.entity.WorkFullSupervisorshee
 import com.jeeplus.modules.workfullsupervisorsheet.service.WorkFullSupervisorsheetService;
 import com.jeeplus.modules.workgoout.entity.GoOut;
 import com.jeeplus.modules.workgoout.service.GoOutService;
+import com.jeeplus.modules.workgooutapply.entity.WorkGoOutInfo;
+import com.jeeplus.modules.workgooutapply.service.WorkGoOutService;
 import com.jeeplus.modules.workincomingmessage.entity.WorkIncomingMessage;
 import com.jeeplus.modules.workincomingmessage.service.WorkIncomingMessageService;
 import com.jeeplus.modules.workinvoice.entity.WorkInvoice;
@@ -414,6 +416,8 @@ public class WorkProjectNotifyController extends BaseController {
 	private WorkContractReService workContractReService;
 	@Autowired
 	private WorkLeaveService workLeaveService;
+	@Autowired
+	WorkGoOutService workGoOutService;
 
 	@ModelAttribute
 	public WorkProjectNotify get(@RequestParam(required=false) String id) {
@@ -706,6 +710,10 @@ public class WorkProjectNotifyController extends BaseController {
 				if(workContractSignature!=null){
 					processInstanceId = workContractSignature.getProcessInstanceId();
 				}
+			}else if("92".equals(workProjectNotify.getType())){	//外出申请
+				WorkGoOutInfo workGoOutInfo = workGoOutService.get(workProjectNotify.getNotifyId());
+				if (workGoOutInfo != null)
+					processInstanceId = workGoOutInfo.getProcessInstanceId();
 			}else if(workProjectNotify.getType().equals("54")){	//收入调整作废
 				WorkReceiptsRevise workReceiptsRevise = workReceiptsReviseService.get(workProjectNotify.getNotifyId());
 				processInstanceId = workReceiptsRevise.getInvalidProcessInstanceId();
@@ -1142,6 +1150,19 @@ public class WorkProjectNotifyController extends BaseController {
 					} else {
 						return "modules/workcontractsignature/workContractSignatureView";
 					}
+				}else if ("92".equals(workProjectNotify.getType())) {    //外出申请
+					WorkGoOutInfo workGoOut = workGoOutService.get(workProjectNotify.getNotifyId());
+					Act act = getByAct(workGoOut.getProcessInstanceId());
+					workGoOut.setAct(act);
+					workGoOut.setHome("home");
+					model.addAttribute("workGoOut", workGoOut);
+					if (workProjectNotify.getRemarks().contains("待审批") && !"1".equals(workProjectNotify.getStatus())) {
+						return "modules/workgoout/workGoOutAudit";
+					} else if (workProjectNotify.getRemarks().contains("重新申请") && !"1".equals(workProjectNotify.getStatus())) {
+						return "modules/workgoout/workGoOutModifyApply";
+					} else {
+						return "modules/workgoout/workGoOutView";
+					}
 				}else if (workProjectNotify.getType().equals("53")) {    //收入调整
 					WorkReceiptsRevise workReceiptsRevise = workReceiptsReviseService.get(workProjectNotify.getNotifyId());
 					workReceiptsRevise.setAct(getByAct(workReceiptsRevise.getProcessInstanceId()));
@@ -2424,6 +2445,10 @@ public class WorkProjectNotifyController extends BaseController {
 					workContractSignature.setHome("home");
 					model.addAttribute("workContractSignature", workContractSignature);
 					return "modules/workcontractsignature/workContractSignatureView";
+				}else if("56".equals(workProjectNotify.getType())){	//外出申请
+					WorkGoOutInfo workGoOut = workGoOutService.get(workProjectNotify.getNotifyId());
+					model.addAttribute("workGoOut", workGoOut);
+					return "modules/workagoout/workworkGoOutView";
 				}
 			}
 		}

+ 19 - 0
src/main/resources/mappings/modules/projectcontentinfo/ProjectReportDataDao.xml

@@ -630,4 +630,23 @@
 		</where>
 	</select>
 
+	<select id="getInvoiceByProjectId" resultType="com.jeeplus.modules.workinvoice.entity.WorkInvoice">
+		select a.id as "id",
+			a.process_instance_id as "processInstanceId",
+			a.number as "number",
+			a.project_id as "projectId",
+			a.money as "money",
+			a.invoice_date as "invoiceDate",
+			a.invoice_state as "invoiceState",
+			a.create_date as "createDate",
+			b.number as "workAccountNumber",
+			b.tax_money as "taxMoney",
+			w.name as "client.name"
+		from work_invoice a
+		left join work_invoice_detail b on a.id=b.invoice_id
+		left join work_client_info w on w.id = a.client_id
+		where a.project_id = #{projectId}
+		order by a.invoice_date desc, b.create_by asc,a.create_by asc
+	</select>
+
 </mapper>

+ 189 - 0
src/main/resources/mappings/modules/workgooutapply/WorkGoOutDao.xml

@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jeeplus.modules.workgooutapply.dao.WorkGoOutDao">
+
+	<sql id="workAdministrativeAtampColumns">
+		a.id AS "id",
+		a.create_by AS "createBy.id",
+		a.create_date AS "createDate",
+		a.update_by AS "updateBy.id",
+		a.update_date AS "updateDate",
+		a.remarks AS "remarks",
+		a.del_flag AS "delFlag",
+		a.office_id AS "office.id",
+		a.company_id AS "company.id",
+		a.doc_type AS "docType",
+		a.num AS "num",
+		a.ext,
+		a.submiter AS "submiter.id",
+		a.submit_date AS "submitDate",
+		a.state AS "state",
+		a.process_instance_id AS "processInstanceId",
+		u1.name AS "submiter.name",
+		o.name AS "office.name",
+		p.project_name AS "project.projectName",
+		p.project_id  AS "project.projectId",
+		a.project_id AS "project.id",
+		o.top_company AS "office.topCompany"
+	</sql>
+
+	<sql id="workAdministrativeAtampJoins">
+		LEFT JOIN sys_office o on a.office_id = o.id
+		LEFT JOIN sys_office s ON s.id = a.company_id
+		LEFT JOIN sys_user u ON u.id = a.create_by
+		LEFT JOIN sys_user u1 ON u1.id = a.submiter
+		LEFT JOIN project_records p ON p.id = a.project_id
+	</sql>
+
+
+	<select id="get" resultType="com.jeeplus.modules.workgooutapply.entity.WorkGoOutInfo" >
+		SELECT
+		<include refid="workAdministrativeAtampColumns"/>
+		FROM work_go_out a
+		<include refid="workAdministrativeAtampJoins"/>
+		WHERE a.id = #{id}
+	</select>
+
+	<select id="findList" resultType="com.jeeplus.modules.workgooutapply.entity.WorkGoOutInfo" >
+		SELECT
+		<include refid="workAdministrativeAtampColumns"/>
+		FROM work_go_out a
+		<include refid="workAdministrativeAtampJoins"/>
+		<where>
+			<if test="beginDate !=null">
+				AND a.submit_date >= #{beginDate}
+			</if>
+			<if test="endDate !=null">
+				AND a.submit_date &lt; #{endDate}
+			</if>
+			<if test="submiter !=null and submiter.name != null and submiter.name!=''">
+				AND u1.name LIKE concat('%',#{submiter.name},'%')
+			</if>
+			<if test="num !=null and num !=''">
+				AND a.num LIKE concat('%',#{num},'%')
+			</if>
+			<if test="docType != null and docType != ''">
+				AND a.doc_type = #{docType}
+			</if>
+			<if test="project != null and project.projectName != null and project.projectName != ''">
+				AND p.project_name LIKE concat('%',#{project.projectName},'%')
+			</if>
+			<if test="state != null">
+				AND a.state = #{state}
+			</if>
+			AND a.del_flag = #{DEL_FLAG_NORMAL}
+			${sqlMap.dsf}
+		</where>
+		<choose>
+			<when test="page !=null and page.orderBy != null and page.orderBy != ''">
+				ORDER BY ${page.orderBy}
+			</when>
+			<otherwise>
+				ORDER BY a.update_date DESC
+			</otherwise>
+		</choose>
+	</select>
+
+    <insert id="insert">
+        INSERT INTO work_go_out(
+        id,
+        create_by,
+        create_date,
+        update_by,
+        update_date,
+        remarks,
+        del_flag,
+        office_id,
+        company_id,
+        doc_type,
+        num,
+        submiter,
+        submit_date,
+        state,
+        project_id,
+        ext,
+        process_instance_id
+        ) VALUES (
+        #{id},
+        #{createBy.id},
+        #{createDate},
+        #{updateBy.id},
+        #{updateDate},
+        #{remarks},
+        #{delFlag},
+        #{office.id},
+        #{company.id},
+        #{docType},
+        #{num},
+        #{submiter.id},
+        #{submitDate},
+        #{state},
+        #{project.id},
+        #{ext},
+        #{processInstanceId}
+        )
+    </insert>
+
+	<update id="update">
+		UPDATE work_go_out SET
+		update_by = #{updateBy.id},
+		update_date = #{updateDate},
+		remarks = #{remarks},
+		office_id = #{office.id},
+		company_id = #{company.id},
+		doc_type = #{docType},
+		num = #{num},
+		submiter = #{submiter.id},
+		submit_date = #{submitDate},
+		state = #{state},
+		ext = #{ext},
+		project_id = #{project.id},
+		process_instance_id = #{processInstanceId}
+		WHERE id = #{id}
+	</update>
+
+    <update id="updateProcessIdAndStatus" >
+        UPDATE  work_go_out SET
+        process_instance_id = #{processInstanceId},
+        state = #{state}
+        WHERE id = #{id}
+    </update>
+
+	<!--物理删除-->
+	<update id="delete">
+		UPDATE work_go_out SET
+		del_flag = #{DEL_FLAG_DELETE}
+		WHERE id = #{id}
+	</update>
+
+    <select id="queryCount" resultType="int" >
+        SELECT COUNT(1)
+        FROM work_go_out a
+        <if test="submiter !=null and submiter.name != null and submiter.name!=''">
+            LEFT JOIN sys_user u1 ON u1.id = a.submiter
+        </if>
+        <where>
+            <if test="beginDate !=null">
+                AND a.submit_date >= #{beginDate}
+            </if>
+            <if test="endDate !=null">
+                AND a.submit_date &lt; #{endDate}
+            </if>
+            <if test="submiter !=null and submiter.name != null and submiter.name!=''">
+                AND u1.name LIKE concat('%',#{submiter.name},'%')
+            </if>
+            <if test="num !=null and num !=''">
+                AND a.num LIKE concat('%',#{num},'%')
+            </if>
+            <if test="docType != null and docType != ''">
+                AND a.doc_type = #{docType}
+            </if>
+            <if test="state != null">
+                AND a.state = #{state}
+            </if>
+            AND a.del_flag = #{DEL_FLAG_NORMAL}
+            ${sqlMap.dsf}
+        </where>
+    </select>
+	
+</mapper>

+ 78 - 0
src/main/webapp/webpage/modules/projectrecord/projectRecordsView.jsp

@@ -65,6 +65,18 @@
 
 			elem.innerHTML = xml;
 		}
+
+        function invoiceStatus(index,id,dataid,status)
+        {
+            var invoiceElem = document.getElementById("invoice_td_" + index);
+            var st = getAuditState(status);
+            if(st.action)
+                var xml = "<span onclick=\"openDialogView('流程追踪', '${ctx}/workinvoice/workInvoice/getProcessOne?id=" + dataid +"','95%','95%')\" class=\"status-label status-label-" + st.label + "\" >" + st.status + "</span>";
+            else
+                var xml = "<span style=\"cursor:default;\" class=\"status-label status-label-" + st.label + "\" >" + st.status + "</span>";
+
+            invoiceElem.innerHTML = xml;
+        }
 	</script>
 </head>
 <body>
@@ -480,6 +492,72 @@
 			</div>
 			</div>
 
+
+			<div class="form-group layui-row">
+				<div class="form-group-label"><h2>项目发票</h2></div>
+				<div class="layui-item layui-col-xs12 form-table-container" >
+					<table id="invoiceList" class="table table-bordered table-condensed details">
+						<thead>
+						<tr>
+							<th>发票编号</th>
+							<th>发票号</th>
+							<th width="30%">开票单位</th>
+							<th>创建时间</th>
+							<th>开票时间</th>
+							<th>价税合计</th>
+							<th>税后金额</th>
+							<th>审批状态</th>
+						</tr>
+						</thead>
+						<tbody>
+						<c:choose>
+							<c:when test="${not empty projectRecords.workInvoices}">
+								<c:forEach items="${projectRecords.workInvoices}" var="invoice" varStatus="index">
+									<tr>
+										<td><a title="${invoice.number}" href="javascript:void(0)" onclick="openDialogView('查看发票详情', '${ctx}/workinvoice/workInvoice/form1?id=${invoice.id}','95%', '95%')">
+												${invoice.number}
+										</a></td>
+										<td>
+												${invoice.workAccountNumber}
+										</td>
+										<td>
+												${invoice.client.name}
+										</td>
+										<td>
+											<fmt:formatDate value="${invoice.createDate}" pattern="yyyy-MM-dd"/>
+										</td>
+										<td>
+											<fmt:formatDate value="${invoice.invoiceDate}" pattern="yyyy-MM-dd"/>
+										</td>
+										<td >
+												${invoice.money}
+										</td>
+										<td >
+												${invoice.taxMoney}
+										</td>
+										<td class="op-td">
+											<div style="text-align: center" id="invoice_td_${index.index+1}">
+											</div>
+											<script>
+                                                invoiceStatus(${index.index+1},"${id}","${invoice.id}","${invoice.invoiceState}");
+											</script>
+										</td>
+									</tr>
+								</c:forEach>
+							</c:when>
+							<c:otherwise>
+								<tr>
+									<td colspan="7">
+										暂无数据
+									</td>
+								</tr>
+							</c:otherwise>
+						</c:choose>
+						</tbody>
+					</table>
+				</div>
+			</div>
+
 			<div class="form-group layui-row">
 				<div class="form-group-label"><h2>项目报告</h2></div>
 				<div class="layui-item layui-col-xs12 form-table-container" >

+ 219 - 0
src/main/webapp/webpage/modules/workgoout/workGoOutAudit.jsp

@@ -0,0 +1,219 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<html>
+<head>
+	<title>外出管理</title>
+	<meta name="decorator" content="default"/>
+    <script type="text/javascript">
+        var validateForm;
+        function doSubmit(obj){//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if(validateForm.form()){
+                if(obj == 1){
+                    $('#flag').val('yes');
+                }else{
+                    $('#flag').val('no');
+                }
+
+                $("#inputForm").submit();
+                return true;
+            }
+
+            return false;
+        }
+        $(document).ready(function() {
+            validateForm = $("#inputForm").validate({
+                submitHandler: function(form){
+                    loading('正在提交,请稍等...');
+                    form.submit();
+                },
+                errorContainer: "#messageBox",
+                errorPlacement: function(error, element) {
+                    $("#messageBox").text("输入有误,请先更正。");
+                    if (element.is(":checkbox")||element.is(":radio")||element.parent().is(".input-append")){
+                        error.appendTo(element.parent().parent());
+                    } else {
+                        error.insertAfter(element);
+                    }
+                }
+            });
+            laydate.render({
+                elem: '#incomeDate', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+            });
+            $("#attachment_btn").click(function () {
+                $("#attachment_file").click();
+            });
+        });
+    </script>
+</head>
+<body>
+    <div class="single-form">
+        <div class="container">
+            <form:form id="inputForm" modelAttribute="workGoOut" action="${ctx}/workgoout/workGoOut/saveAudit" method="post" class="form-horizontal">
+                <form:hidden path="id"/>
+                <form:hidden path="home"/>
+                <form:hidden path="act.taskId"/>
+                <form:hidden path="act.taskName"/>
+                <form:hidden path="act.taskDefKey"/>
+                <form:hidden path="act.procInsId"/>
+                <form:hidden path="act.procDefId"/>
+                <form:hidden path="project.id"/>
+                <form:hidden id="flag" path="act.flag"/>
+                <div class="form-group layui-row first">
+                    <div class="form-group-label"><h2>基本信息</h2></div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label">外出类型:</label>
+                        <div class="layui-input-block">
+                            <input readonly="true" htmlEscape="false" class="form-control layui-input"
+                                   value="<c:choose><c:when test="${workGoOut.ext == 0}">项目外出</c:when><c:otherwise>非项目外出</c:otherwise></c:choose>"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label">项目名称:</label>
+                        <div class="layui-input-block">
+                            <form:input  path="project.projectName" htmlEscape="false" readonly="true" class="form-control  layui-input"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label">项目编号:</label>
+                        <div class="layui-input-block">
+                            <form:input  path="project.projectId" htmlEscape="false" readonly="true" class="form-control  layui-input"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请编号:</label>
+                        <div class="layui-input-block">
+                            <div class="input-group">
+                                <form:input path="num" htmlEscape="false"  readonly="true"  class="form-control  layui-input"/>
+                                <span class="input-group-btn">
+                                <label class="form-status"><c:choose><c:when test="${not empty workGoOut.state}">${fns:getDictLabel(workGoOut.state, 'audit_state', '')}</c:when><c:otherwise>新添</c:otherwise></c:choose></label>
+                             </span>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请人:</label>
+                        <div class="layui-input-block">
+                            <form:input path="submiter.name" htmlEscape="false" readonly="true" class="form-control layui-input required"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label">所属部门:</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="office.name" readonly="readonly" class="form-control layui-input"  value="${workGoOut.office.topCompany}"/>
+                            <input type="hidden" name="office.id" readonly="readonly" class="form-control layui-input"  value="${workGoOut.office.id}"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请日期:</label>
+                        <div class="layui-input-block">
+                            <input type="text" readonly="readonly" class="form-control layui-input"
+                                   value="<fmt:formatDate value="${workGoOut.submitDate}" pattern="yyyy-MM-dd"/>"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm12 with-textarea">
+                        <label class="layui-form-label">说    明:</label>
+                        <div class="layui-input-block">
+                            <form:textarea path="remarks" readonly="true" htmlEscape="false" rows="3" class="form-control"/>
+                        </div>
+                    </div>
+                </div>
+                <div class="form-group layui-row">
+                    <div class="form-group-label"><h2>项目计划附件信息</h2></div>
+                    <div class="layui-item layui-col-xs12 form-table-container" >
+                        <table id="listAttachment" class="table table-bordered table-condensed no-bottom-margin details">
+                            <thead>
+                            <tr>
+                                    <%-- <th>序号</th>--%>
+                                <th>文件预览</th>
+                                <th>上传人</th>
+                                <th>上传时间</th>
+                                <th width="150px">操作</th>
+                            </tr>
+                            </thead>
+                            <tbody id="file_attachment">
+                            <c:forEach items="${workGoOut.workAttachments}" var = "workClientAttachment" varStatus="status">
+                                <tr>
+                                        <%-- <td>${status.index + 1}</td>--%>
+                                    <c:choose>
+                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                            <td><img src="${workClientAttachment.url}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.url}','90%','90%')" alt="${workClientAttachment.attachmentName}"></td>
+                                        </c:when>
+                                        <c:otherwise>
+                                            <c:choose>
+                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="preview('预览','${workClientAttachment.url}','90%','90%','1')">${workClientAttachment.attachmentName}</a></td>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="preview('预览','${workClientAttachment.url}','90%','90%')">${workClientAttachment.attachmentName}</a></td>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </c:otherwise>
+                                    </c:choose>
+                                    <td>${workClientAttachment.createBy.name}</td>
+                                    <td><fmt:formatDate value="${workClientAttachment.createDate}" type="both"/></td>
+                                    <td class="op-td">
+                                        <div class="op-btn-box" >
+                                            <c:set var="signflag" value="${fns:getSysParam('sign_flag',fns:getUser())}"/>
+                                            <c:choose>
+                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'doc')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'docx')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'xls')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'xlsx')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'ppt')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'pptx')}">
+                                                    <c:if test="${workGoOut.act.taskDefKey eq 'gzr'}">
+                                                        <a href="${ctx}/isignature/iSignatureDocument/sign?recordId=${workClientAttachment.id}" class="op-btn op-btn-sign" target="_blank">签章</a>
+                                                    </c:if>
+                                                    <a href="javascript:void(0);" onclick="openDialogView('查看电子签章信息', '${ctx}/isignature/iSignatureDocument/form?recordId=${workClientAttachment.id}','95%', '95%')" class="op-btn op-btn-view" ><i class="fa fa-search-plus"></i> 查看</a>
+                                                    <c:choose>
+                                                        <c:when test="${signflag == '是'}">
+                                                            <a href="javascript:location.href='${ctx}/isignature/iSignatureDocument/download?recordId=${workClientAttachment.id}'" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                        </c:when>
+                                                        <c:otherwise>
+                                                            <a href="javascript:location.href='${ctx}/workfullmanage/workFullManage/downLoadAttach?file='+encodeURIComponent(encodeURIComponent('${workClientAttachment.url}'));" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                        </c:otherwise>
+                                                    </c:choose>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <a href="javascript:location.href='${ctx}/workfullmanage/workFullManage/downLoadAttach?file='+encodeURIComponent(encodeURIComponent('${workClientAttachment.url}'));" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:forEach>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+                <div class="form-group layui-row">
+                    <div class="form-group-label"><h2>审批意见</h2></div>
+                    <div class="layui-item layui-col-xs12 with-textarea" >
+                        <label class="layui-form-label">审批意见:</label>
+                        <div class="layui-input-block">
+                            <form:textarea path="act.comment" class="form-control" rows="4" maxlength="127" />
+                            <input type="file" name="upload_files" style="display: none;">
+                        </div>
+                    </div>
+                </div>
+                <div class="form-group layui-row">
+                    <div class="form-group-label"><h2>审批流程</h2></div>
+                    <div class="layui-item layui-col-xs12 form-table-container" >
+                        <act:flowChart procInsId="${workGoOut.act.procInsId}"/>
+                        <act:histoicFlow procInsId="${workGoOut.act.procInsId}"/>
+                    </div>
+                </div>
+
+                <div class="form-group layui-row page-end"></div>
+	        </form:form>
+        </div>
+    </div>
+</body>
+</html>

+ 231 - 0
src/main/webapp/webpage/modules/workgoout/workGoOutForm.jsp

@@ -0,0 +1,231 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<html>
+<head>
+	<title>外出管理</title>
+	<meta name="decorator" content="default"/>
+    <style>
+        label.error{
+            left:0px;
+            top:40px;
+        }
+    </style>
+	<script type="text/javascript">
+		var validateForm;
+		function doSubmit(i){//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if(validateForm.form()){
+                if(i==2){
+                    $("#inputForm").attr("action","${ctx}/workgoout/workGoOut/tstore");
+                }
+                $("#inputForm").submit();
+                return true;
+            }
+	
+		  return false;
+		}
+        $(document).ready(function() {
+            $("input[name='ext']").on('ifChecked', function(event){
+                var radioVal = $(this).val();
+                if(radioVal == 0){
+                    $(".td1").removeClass("hide");
+                }else{
+                    $(".td1").addClass("hide");
+                }
+            });
+            if("${workReimbursement.ext}" == "1"){
+                $("#ext1").iCheck('check')
+            }else{
+                $("#ext").iCheck('check')
+            }
+            validateForm = $("#inputForm").validate({
+                submitHandler: function(form){
+                    loading('正在提交,请稍等...');
+                    form.submit();
+                },
+                errorContainer: "#messageBox",
+                errorPlacement: function(error, element) {
+                    $("#messageBox").text("输入有误,请先更正。");
+                    if (element.is(":checkbox")||element.is(":radio")||element.parent().is(".input-append")){
+                        error.appendTo(element.parent().parent());
+                    } else {
+                        error.insertAfter(element);
+                    }
+                }
+            });
+            $("#attachment_btn").click(function () {
+                $("#attachment_file").click();
+            });
+        });
+
+        function insertTitle(tValue){
+            var list = "${workGoOut.workAttachments}";
+            var size = (list.split('url')).length-1;
+            var files = $("#attachment_file")[0].files;            for(var i = 0;i<files.length;i++) {                var file = files[i];
+            var attachmentId = "";
+            var attachmentFlag = "102";
+            console.log(file);
+            var timestamp=new Date().getTime();
+
+            var storeAs = "attachment-file/workIncomingMessage/"+timestamp+"/"+file['name'];
+            var uploadPath="http://gangwan-app.oss-cn-hangzhou.aliyuncs.com/"+storeAs;/*将这段字符串存到数据库即可*/
+            var divId = "_attachment";
+            $("#addFile"+divId).show();
+            multipartUploadWithSts(storeAs, file,attachmentId,attachmentFlag,uploadPath,divId,size);}
+        }
+        function setPNumber(obj){
+            $.ajax({
+                type:'post',
+                url:'${ctx}/workinvoice/workInvoice/getPNumber',
+                data:{
+                    "obj":obj
+                },
+                success:function(data){
+                    var d = JSON.parse(data);
+                    $("#pNumber").val(d.pNumber);
+                    $("#cInfoName").val(d.cInfoName);
+                    $("#cName").val(d.cName);
+                }
+            })
+        }
+	</script>
+</head>
+<body>
+    <div class="single-form">
+        <div class="container">
+            <form:form id="inputForm" modelAttribute="workGoOut" action="${ctx}/workgoout/workGoOut/save" method="post" class="form-horizontal">
+            <form:hidden path="id"/>
+                <div class="form-group layui-row first">
+                    <div class="form-group-label"><h2>基本信息</h2></div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>外出类型:</label>
+                        <div class="layui-input-block">
+                            <input type="radio" class="i-checks" name="ext" checked id="ext" value="0">
+                            <label for="ext">项目外出</label>
+                            <input type="radio" class="i-checks" name="ext" id="ext1" value="1">
+                            <label for="ext1">非项目外出</label>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6 td1">
+                        <label class="layui-form-label"><span class="require-item">*</span>项目名称:</label>
+                        <div class="layui-input-block  with-icon">
+                            <input type="hidden" value="" id ="ids">
+                            <sys:gridselectcallprojectt url="${ctx}/workinvoice/workInvoice/selectproject" id="project" name="project.id"  value="${workGoOut.project.id}"  title="选择所属项目" labelName="projectApproval.project.projectName"
+                                                        labelValue="${workGoOut.project.projectName}" cssClass="form-control required layui-input" fieldLabels="项目" fieldKeys="projectName" searchLabel="项目名称" searchKey="projectName" ></sys:gridselectcallprojectt>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6 td1">
+                        <label class="layui-form-label"><span class="require-item">*</span>项目编号:</label>
+                        <div class="layui-input-block">
+                            <form:input id ="pNumber" path="project.projectId" htmlEscape="false"  readonly="true" class="form-control layui-input"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请编号:</label>
+                        <div class="layui-input-block">
+                            <div class="input-group">
+                                <form:input path="num" htmlEscape="false"  readonly="true"  class="form-control  layui-input"/>
+                                <span class="input-group-btn">
+                                <label class="form-status"><c:choose><c:when test="${not empty workGoOut.state}">${fns:getDictLabel(workGoOut.state, 'audit_state', '')}</c:when><c:otherwise>新添</c:otherwise></c:choose></label>
+                             </span>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请人:</label>
+                        <div class="layui-input-block">
+                            <form:input path="submiter.name" htmlEscape="false" readonly="true" class="form-control layui-input required"/>
+                            <form:hidden path="submiter.id" htmlEscape="false"    class="form-control required"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label">所属部门:</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="office.name" readonly="readonly" class="form-control layui-input"  value="${workGoOut.office.topCompany}"/>
+                            <input type="hidden" name="office.id" readonly="readonly" class="form-control layui-input"  value="${workGoOut.office.id}"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请日期:</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="submitDate" readonly="readonly" class="form-control layui-input"
+                                   value="<fmt:formatDate value="${workGoOut.submitDate}" pattern="yyyy-MM-dd"/>"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm12 with-textarea">
+                        <label class="layui-form-label">说    明:</label>
+                        <div class="layui-input-block">
+                            <form:textarea path="remarks" htmlEscape="false" rows="3" maxlength="255" class="form-control"/>
+                        </div>
+                    </div>
+                </div>
+                <div class="form-group layui-row">
+                    <div class="form-group-label"><h2>附件信息</h2></div>
+                    <div class="layui-item nav-btns">
+                        <a id="attachment_btn" class="nav-btn nav-btn-add" title="添加附件"><i class="fa fa-plus"></i>&nbsp;添加附件</a>
+                    </div>
+                    <div id="addFile_attachment" style="display: none" class="upload-progress">
+                        <span id="fileName_attachment" ></span>
+                        <b><span id="baifenbi_attachment" ></span></b>
+                        <div class="progress">
+                            <div id="jindutiao_attachment" class="progress-bar" style="width: 0%" aria-valuenow="0">
+                            </div>
+                        </div>
+                    </div>
+                    <input id="attachment_file" type="file" name="attachment_file" multiple="multiple" style="display: none;" onChange="if(this.value)insertTitle(this.value);"/>
+                    <span id="attachment_title"></span>
+                    <div class="layui-item layui-col-xs12" style="padding:0 16px;">
+                        <table id="upTable" class="table table-bordered table-condensed details">
+                            <thead>
+                            <tr>
+                                    <%-- <th>序号</th>--%>
+                                <th>文件预览</th>
+                                <th>上传人</th>
+                                <th>上传时间</th>
+                                <th width="150px">操作</th>
+                            </tr>
+                            </thead>
+                            <tbody id="file_attachment">
+                            <c:forEach items="${workGoOut.workAttachments}" var = "workClientAttachment" varStatus="status">
+                                <tr>
+                                        <%-- <td>${status.index + 1}</td>--%>
+                                    <c:choose>
+                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                            <td><img src="${workClientAttachment.url}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.url}','90%','90%')" alt="${workClientAttachment.attachmentName}"></td>
+                                        </c:when>
+                                        <c:otherwise>
+                                            <c:choose>
+                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="preview('预览','${workClientAttachment.url}','90%','90%','1')">${workClientAttachment.attachmentName}</a></td>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="preview('预览','${workClientAttachment.url}','90%','90%')">${workClientAttachment.attachmentName}</a></td>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </c:otherwise>
+                                    </c:choose>
+                                    <td>${workClientAttachment.createBy.name}</td>
+                                    <td><fmt:formatDate value="${workClientAttachment.createDate}" type="both"/></td>
+                                    <td class="op-td">
+                                        <div class="op-btn-box" >
+                                            <a href="javascript:location.href='${ctx}/workfullmanage/workFullManage/downLoadAttach?file='+encodeURIComponent(encodeURIComponent('${workClientAttachment.url}'));" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+
+                                            <c:if test="${workClientAttachment.createBy.id eq fns:getUser().id}">
+                                                <a href="javascript:void(0)" onclick="deleteFileFromAliyun(this,'${ctx}/sys/workattachment/deleteFileFromAliyun?url=${workClientAttachment.url}&id=${workClientAttachment.id}&type=2','addFile')" class="op-btn op-btn-delete" ><i class="fa fa-trash"></i>&nbsp;删除</a>
+                                            </c:if>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:forEach>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+	        </form:form>
+        </div>
+    </div>
+</body>
+</html>

+ 319 - 0
src/main/webapp/webpage/modules/workgoout/workGoOutList.jsp

@@ -0,0 +1,319 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<html>
+<head>
+	<title>外出管理</title>
+	<meta name="decorator" content="default"/>
+    <style>
+        .widthClass{
+            display: inline-block;
+        }
+        .shows .input-group{
+            width: 48%!important;
+        }
+    </style>
+    <style>
+        body{
+            background-color:transparent;
+            filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#26FFFFFF, endColorstr=#26FFFFFF);
+            color:#ffffff;
+            background-color:rgba(255,255,255,0);
+            height:100%;
+        }
+    </style>
+    <script type="text/javascript">
+        $(document).ready(function() {
+            $("#cus_name").show();
+            $("#cus_name").siblings().hide();
+            //搜索框收放
+            $('#moresee').click(function(){
+                if($('#moresees').is(':visible'))
+                {
+                    $('#moresees').slideUp(0,resizeListWindow1);
+                    $('#moresee i').removeClass("glyphicon glyphicon-menu-up").addClass("glyphicon glyphicon-menu-down");
+                }else{
+                    $('#moresees').slideDown(0,resizeListWindow1);
+                    $('#moresee i').removeClass("glyphicon glyphicon-menu-down").addClass("glyphicon glyphicon-menu-up");
+                }
+            });
+            laydate.render({
+                elem: '#beginDate', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+            });
+            laydate.render({
+                elem: '#endDate', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+            });
+        });
+
+        function openDialog(title,url,width,height,target) {
+
+            if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {//如果是移动端,就使用自适应大小弹窗
+                width = 'auto';
+                height = 'auto';
+            } else {//如果是PC端,根据用户设置的width和height显示。
+
+            }
+
+            top.layer.open({
+                type: 2,
+                area: [width, height],
+                title: title,
+                maxmin: true, //开启最大化最小化按钮
+                content: url,
+                skin: 'three-btns',
+                btn: ['送审', '暂存', '关闭'],
+                btn1: function(index, layero){
+                    var body = top.layer.getChildFrame('body', index);
+                    var iframeWin = layero.find('iframe')[0]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
+                    var inputForm = body.find('#inputForm');
+                    var top_iframe;
+                    if(target){
+                        top_iframe = target;//如果指定了iframe,则在改frame中跳转
+                    }else{
+                        top_iframe = top.getActiveTab().attr("name");//获取当前active的tab的iframe
+                    }
+                    inputForm.attr("target",top_iframe);//表单提交成功后,从服务器返回的url在当前tab中展示
+                    if(iframeWin.contentWindow.doSubmit(1) ){
+                        setTimeout(function(){top.layer.close(index)}, 100);//延时0.1秒,对应360 7.1版本bug
+                    }
+                },
+                btn2:function(index,layero){
+                    var body = top.layer.getChildFrame('body', index);
+                    var iframeWin = layero.find('iframe')[0]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
+                    var inputForm = body.find('#inputForm');
+                    var top_iframe;
+                    if(target){
+                        top_iframe = target;//如果指定了iframe,则在改frame中跳转
+                    }else{
+                        top_iframe = top.getActiveTab().attr("name");//获取当前active的tab的iframe
+                    }
+                    inputForm.attr("target",top_iframe);//表单提交成功后,从服务器返回的url在当前tab中展示
+                    if(iframeWin.contentWindow.doSubmit(2) ){
+                        setTimeout(function(){top.layer.close(index)}, 100);//延时0.1秒,对应360 7.1版本bug
+                    }else {
+                        return false;
+                    }
+                },
+                btn3: function (index) {
+                }
+            });
+        }
+        function openDialogre(title,url,width,height,target,buttons) {
+
+            if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {//如果是移动端,就使用自适应大小弹窗
+                width = 'auto';
+                height = 'auto';
+            } else {//如果是PC端,根据用户设置的width和height显示。
+
+            }
+            var split = buttons.split(",");
+            top.layer.open({
+                type: 2,
+                area: [width, height],
+                title: title,
+                maxmin: true, //开启最大化最小化按钮
+                skin: 'three-btns',
+                content: url,
+                btn: split,
+                btn1: function(index, layero){
+                    var body = top.layer.getChildFrame('body', index);
+                    var iframeWin = layero.find('iframe')[0]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
+                    var inputForm = body.find('#inputForm');
+                    var top_iframe;
+                    if(target){
+                        top_iframe = target;//如果指定了iframe,则在改frame中跳转
+                    }else{
+                        top_iframe = top.getActiveTab().attr("name");//获取当前active的tab的iframe
+                    }
+                    inputForm.attr("target",top_iframe);//表单提交成功后,从服务器返回的url在当前tab中展示
+                    if(iframeWin.contentWindow.doSubmit(1) ){
+                        setTimeout(function(){top.layer.close(index)}, 100);//延时0.1秒,对应360 7.1版本bug
+                    }
+                },
+                btn2:function(index,layero){
+                    if(split.length==2){return}
+                    var body = top.layer.getChildFrame('body', index);
+                    var iframeWin = layero.find('iframe')[0]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
+                    var inputForm = body.find('#inputForm');
+                    var top_iframe;
+                    if(target){
+                        top_iframe = target;//如果指定了iframe,则在改frame中跳转
+                    }else{
+                        top_iframe = top.getActiveTab().attr("name");//获取当前active的tab的iframe
+                    }
+                    inputForm.attr("target",top_iframe);//表单提交成功后,从服务器返回的url在当前tab中展示
+                    if(iframeWin.contentWindow.doSubmit(2) ){
+                        setTimeout(function(){top.layer.close(index)}, 100);//延时0.1秒,对应360 7.1版本bug
+                    }else {
+                        return false;
+                    }
+                },
+                btn3: function (index) {
+                }
+            });
+        }
+    </script>
+</head>
+<body>
+    <div class="wrapper wrapper-content">
+        <sys:message content="${message}"/>
+        <div class="layui-row">
+            <div class="full-width fl">
+                <div class="contentShadow layui-row" id="queryDiv">
+                    <form:form id="searchForm" modelAttribute="workGoOutInfo" action="${ctx}/workgoout/workGoOut/" method="post" class="form-inline">
+                        <input id="pageNo" name="pageNo" type="hidden" value="${page.pageNo}"/>
+                        <input id="pageSize" name="pageSize" type="hidden" value="${page.pageSize}"/>
+                        <table:sortColumn id="orderBy" name="orderBy" value="${page.orderBy}" callback="sortOrRefresh();"/><!-- 支持排序 -->
+                        <div class="commonQuery">
+                                <div class="layui-item query athird">
+                                    <label class="layui-form-label">项目名称:</label>
+                                    <div class="layui-input-block">
+                                        <form:input path="project.projectName" htmlEscape="false" maxlength="64"  class=" form-control layui-input"/>
+                                    </div>
+                                </div>
+                            <div class="layui-item query athird">
+                                <label class="layui-form-label">申请人:</label>
+                                <div class="layui-input-block">
+                                    <form:input path="submiter.name" htmlEscape="false" maxlength="64"  class=" form-control layui-input"/>
+                                </div>
+                            </div>
+                            <div class="layui-item athird">
+                                <div class="input-group">
+                                    <a href="#" id="moresee"><i class="glyphicon glyphicon-menu-down"></i></a>
+                                    <button id="searchReset" class="fixed-btn searchReset fr" onclick="resetSearch()">重置</button>
+                                    <button id="searchQuery" class="fixed-btn searchQuery fr" onclick="search()">查询</button>
+                                </div>
+                            </div>
+                            <div style="    clear:both;"></div>
+                         </div>
+                        <div id="moresees" style="clear:both;display:none;">
+                            <div class="layui-item query athird">
+                                <label class="layui-form-label">申请编号:</label>
+                                <div class="layui-input-block">
+                                    <form:input path="num" htmlEscape="false" maxlength="64"  class=" form-control layui-input"/>
+                                </div>
+                            </div>
+                            <div class="layui-item query athird">
+                                <label class="layui-form-label">申请状态:</label>
+                                <div class="layui-input-block">
+                                    <form:select path="state" class="form-control simple-select">
+                                        <form:option value="" label=""/>
+                                        <form:options items="${fns:getDictList('audit_state')}" itemLabel="label" itemValue="value" htmlEscape="false"/>
+                                    </form:select>
+                                </div>
+                            </div>
+                        </div>
+                    </form:form>
+	            </div>
+	        </div>
+	
+	<!-- 工具栏 -->
+            <div class="full-width fl">
+                <div class="contentShadow layui-form contentDetails">
+                    <div class="nav-btns">
+                        <shiro:hasPermission name="workgoout:workGoOut:add">
+                            <table:addRow url="${ctx}/workgoout/workGoOut/form" title="项目盖章"></table:addRow><!-- 增加按钮 -->
+                        </shiro:hasPermission>
+                        <button class="nav-btn nav-btn-refresh" data-toggle="tooltip" data-placement="left" onclick="sortOrRefresh()" title="刷新"><i class="glyphicon glyphicon-repeat"></i>&nbsp;刷新</button>
+                        <div style="clear: both;"></div>
+                    </div>
+                    <table class="oa-table layui-table" id="contentTable"></table>
+
+                    <!-- 分页代码 -->
+                    <table:page page="${page}"></table:page>
+                    <div style="clear: both;"></div>
+	            </div>
+	        </div>
+        </div>
+        <div id="changewidth"></div>
+    </div>
+    <script src="${ctxStatic}/layer-v2.3/layui/layui.all.js" charset="utf-8"></script>
+    <script>
+        layui.use('table', function(){
+            layui.table.render({
+                limit:${ page.pageSize }
+                ,elem: '#contentTable'
+                ,page: false
+                ,cols: [[
+                    {field:'index',align:'center', title: '序号',width:40}
+                    ,{field:'num',align:'center', title: '申请编号',minWidth:200,templet:function(d){
+                            var xml = "<a class=\"attention-info\" href=\"javascript:void(0);\" onclick=\"openDialogView('查看外出申请', '${ctx}/workgoout/workGoOut/view?id="+d.id+"','95%','95%')\">" +
+                                "<span title=" + d.num + ">" + d.num + "</span></a>";
+                            return xml;
+                        }}
+                    // ,{field:'docType',align:'center', title: '文档类型',minWidth:150}
+                    ,{field:'comSign',align:'center', title: '项目名称',minWidth:150}
+                    ,{field:'submiter',align:'center', title: '申请人', minWidth:150}
+                    ,{field:'submitDate', align:'center',sort:true,title: '申请日期',minWidth:200}
+                    ,{align:'center', title: '申请状态',  width:70,templet:function(d){
+                            var st = getAuditState(d.state)
+                            var xml = "<span onclick=\"openDialogView('流程追踪', '${ctx}/workgoout/workGoOut/getProcess?id=" + d.id + "','95%','95%')\" class=\"status-label status-label-" + st.label + "\" >" + st.status + "</span>";
+                            return xml;
+                        }}
+                    ,{align:'center',title:"操作",width:130,templet:function(d){
+                            ////对操作进行初始化
+                            var xml = "";
+
+                            if(d.canedit != undefined && d.canedit == "1"){
+                                xml +="<a href=\"javascript:void(0)\" onclick=\"openDialog('修改外出申请', '${ctx}/workgoout/workGoOut/form?id=" + d.id+"','95%','95%')\" class=\"op-btn op-btn-edit\" ><i class=\"fa fa-edit\"></i>修改</a>"
+                            }
+                            if(d.canmodify != undefined && d.canmodify =="1"){
+                                xml+="<a href=\"#\" onclick=\"openDialogre('修改外出申请', '${ctx}/workgoout/workGoOut/form?id=" + d.id + "&tabId=3','95%','95%','','送审,关闭')\" class=\"op-btn op-btn-edit\" ><i class=\"fa fa-edit\"></i> 修改</a>";
+                            }
+                            if(d.canrecall != undefined && d.canrecall =="1"){
+                                xml+="<a href=\"#\" onclick=\"openDialogre('修改外出申请', '${ctx}/workgoout/workGoOut/form?id=" + d.id + "','95%', '95%','','送审,关闭')\" class=\"op-btn op-btn-edit\" ><i class=\"fa fa-edit\"></i> 修改</a>";
+                            }
+                            if(d.candelete != undefined && d.candelete == "1"){
+                                xml +="<a href=\"${ctx}/workgoout/workGoOut/delete?id=" + d.id+"\" onclick=\"return confirmx('确认要删除该外出申请吗?', this.href)\"   class=\"op-btn op-btn-delete\"><i class=\"fa fa-trash\"></i> 删除</a>";
+                            }
+                            if(d.cancancel != undefined && d.cancancel =="1"){
+                                xml+="<a href=\"${ctx}/workgoout/workGoOut/revoke?id=" + d.id + "&processInstanceId=" + d.procId + "\" onclick=\"return confirmx('确认要撤回该外出申请审批吗?', this.href)\" class=\"op-btn op-btn-cancel\" ><i class=\"glyphicon glyphicon-share-alt\"></i> 撤回</a>";
+                            }
+
+                            return xml;
+                        }}
+                ]]
+                ,data: [
+                    <c:if test="${ not empty page.list}">
+                    <c:forEach items="${page.list}" var="workGoOut" varStatus="index">
+                    <c:if test="${index.index != 0}">,</c:if>
+                    {
+                        "index":"${index.index+1}"
+                        ,"id":"${workGoOut.id}"
+                        ,"num":"<c:out value="${workGoOut.num}" escapeXml="true"/>"
+                        ,'docType':"${fns:getMainDictLabel(workGoOut.docType, 'sign_doc_type', '')}"
+                        ,'comSign':"${workGoOut.project.projectName}"
+                        ,'submiter':"${workGoOut.submiter.name}"
+                        ,"submitDate":"<fmt:formatDate value="${workGoOut.submitDate}" pattern="yyyy-MM-dd"/>"
+                        ,"state":"${workGoOut.state}"
+                        ,"procId":"${workGoOut.processInstanceId}"
+                        <c:if test="${flag == '1' or fns:getUser().id == workGoOut.createBy.id}">
+                        <shiro:hasPermission name="workgoout:workGoOut:edit">,"canedit":<c:choose><c:when test="${workGoOut.state == 1 }">"1"</c:when><c:otherwise>"0"</c:otherwise></c:choose>
+                        ,"canmodify":<c:choose><c:when test="${workGoOut.state == 4}">"1"</c:when><c:otherwise>"0"</c:otherwise></c:choose>
+                        ,"canrecall":<c:choose><c:when test="${ workGoOut.state == 3}">"1"</c:when><c:otherwise>"0"</c:otherwise></c:choose>
+                        </shiro:hasPermission>
+                        <shiro:hasPermission name="workgoout:workGoOut:del">,"candelete":<c:choose><c:when test="${workGoOut.state == 1 or workGoOut.state == 3 or workGoOut.state == 4}">"1"</c:when><c:otherwise>"0"</c:otherwise></c:choose></shiro:hasPermission>
+                        ,"cancancel":<c:choose><c:when test="${workGoOut.state == 2}">"1"</c:when><c:otherwise>"0"</c:otherwise></c:choose>
+                        </c:if>
+                    }
+                    </c:forEach>
+                    </c:if>
+                ]
+            });
+
+        })
+
+        resizeListTable(130);/*消除由于有竖向滚动条造成table出现横向滚动条*/
+        $("a").on("click",addLinkVisied);
+    </script>
+    <script>
+        resizeListWindow1();
+        $(window).resize(function(){
+            resizeListWindow1();
+        });
+    </script>
+</body>
+</html>

+ 239 - 0
src/main/webapp/webpage/modules/workgoout/workGoOutModifyApply.jsp

@@ -0,0 +1,239 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<html>
+<head>
+	<title>外出管理</title>
+	<meta name="decorator" content="default"/>
+	<script type="text/javascript">
+		var validateForm;
+		function doSubmit(){//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if(validateForm.form()){
+                $("#inputForm").submit();
+                return true;
+            }
+	
+		  return false;
+		}
+        $(document).ready(function() {
+            $("input[name='ext']").on('ifChecked', function(event){
+                var radioVal = $(this).val();
+                if(radioVal == 0){
+                    $(".td1").removeClass("hide");
+                }else{
+                    $(".td1").addClass("hide");
+                }
+            });
+            if("${workReimbursement.ext}" == "1"){
+                $("#ext1").iCheck('check')
+            }else{
+                $("#ext").iCheck('check')
+            }
+            validateForm = $("#inputForm").validate({
+                submitHandler: function(form){
+                    loading('正在提交,请稍等...');
+                    form.submit();
+                },
+                errorContainer: "#messageBox",
+                errorPlacement: function(error, element) {
+                    $("#messageBox").text("输入有误,请先更正。");
+                    if (element.is(":checkbox")||element.is(":radio")||element.parent().is(".input-append")){
+                        error.appendTo(element.parent().parent());
+                    } else {
+                        error.insertAfter(element);
+                    }
+                }
+            });
+            $("#attachment_btn").click(function () {
+                $("#attachment_file").click();
+            });
+        });
+
+        function insertTitle(tValue){
+            var list = "${workGoOut.workAttachments}";
+            var size = (list.split('url')).length-1;
+            var files = $("#attachment_file")[0].files;            for(var i = 0;i<files.length;i++) {                var file = files[i];
+            var attachmentId = "";
+            var attachmentFlag = "102";
+            console.log(file);
+            var timestamp=new Date().getTime();
+
+            var storeAs = "attachment-file/workIncomingMessage/"+timestamp+"/"+file['name'];
+            var uploadPath="http://gangwan-app.oss-cn-hangzhou.aliyuncs.com/"+storeAs;/*将这段字符串存到数据库即可*/
+            var divId = "_attachment";
+            $("#addFile"+divId).show();
+            multipartUploadWithSts(storeAs, file,attachmentId,attachmentFlag,uploadPath,divId,size);}
+        }
+        function setPNumber(obj){
+            $.ajax({
+                type:'post',
+                url:'${ctx}/workinvoice/workInvoice/getPNumber',
+                data:{
+                    "obj":obj
+                },
+                success:function(data){
+                    var d = JSON.parse(data);
+                    $("#pNumber").val(d.pNumber);
+                    $("#cInfoName").val(d.cInfoName);
+                    $("#cName").val(d.cName);
+                }
+            })
+        }
+	</script>
+</head>
+<body>
+    <div class="single-form">
+        <div class="container">
+            <form:form id="inputForm" modelAttribute="workGoOut" action="${ctx}/workgoout/workGoOut/saveAudit" method="post" class="form-horizontal">
+                <form:hidden path="id"/>
+                <form:hidden path="home"/>
+                <form:hidden path="act.taskId"/>
+                <form:hidden path="act.taskName"/>
+                <form:hidden path="act.taskDefKey"/>
+                <form:hidden path="act.procInsId"/>
+                <form:hidden path="act.procDefId"/>
+                <form:hidden id="flag" path="act.flag"/>
+                <div class="form-group layui-row first">
+                    <div class="form-group-label"><h2>基本信息</h2></div>
+                    <%--<div class="layui-item layui-col-sm6">--%>
+                        <%--<label class="layui-form-label"><span class="require-item">*</span>文档类型:</label>--%>
+                        <%--<div class="layui-input-block">--%>
+                            <%--<form:select path="docType" class="form-control simple-select required">--%>
+                                <%--<form:option value="" label=""/>--%>
+                                <%--<form:options items="${fns:getMainDictList('doc_type')}" itemLabel="label" itemValue="value" htmlEscape="false"/>--%>
+                            <%--</form:select>--%>
+                        <%--</div>--%>
+                    <%--</div>--%>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>外出类型:</label>
+                        <div class="layui-input-block">
+                            <input type="radio" class="i-checks" name="ext" checked id="ext" value="0">
+                            <label for="ext">项目外出</label>
+                            <input type="radio" class="i-checks" name="ext" id="ext1" value="1">
+                            <label for="ext1">非项目外出</label>
+                                <%--<input type="text" name="title" lay-verify="title" autocomplete="off" readonly="true" placeholder="" class="layui-input" value="全过程管理用户01">--%>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6 td1">
+                        <label class="layui-form-label"><span class="require-item">*</span>项目名称:</label>
+                        <div class="layui-input-block  with-icon">
+                            <input type="hidden" value="" id ="ids">
+                            <sys:gridselectcallprojectt url="${ctx}/workinvoice/workInvoice/selectproject" id="project" name="project.id"  value="${workGoOut.project.id}"  title="选择所属项目" labelName="projectApproval.project.projectName"
+                                                        labelValue="${workGoOut.project.projectName}" cssClass="form-control required layui-input" fieldLabels="项目" fieldKeys="projectName" searchLabel="项目名称" searchKey="projectName" ></sys:gridselectcallprojectt>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6 td1">
+                        <label class="layui-form-label"><span class="require-item">*</span>项目编号:</label>
+                        <div class="layui-input-block">
+                            <form:input id ="pNumber" path="project.projectId" htmlEscape="false"  readonly="true" class="form-control layui-input"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请编号:</label>
+                        <div class="layui-input-block">
+                            <div class="input-group">
+                                <form:input path="num" htmlEscape="false"  readonly="true"  class="form-control  layui-input"/>
+                                <span class="input-group-btn">
+                                <label class="form-status"><c:choose><c:when test="${not empty workGoOut.state}">${fns:getDictLabel(workGoOut.state, 'audit_state', '')}</c:when><c:otherwise>新添</c:otherwise></c:choose></label>
+                             </span>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请人:</label>
+                        <div class="layui-input-block">
+                            <form:input path="submiter.name" htmlEscape="false" readonly="true" class="form-control layui-input required"/>
+                            <form:hidden path="submiter.id" htmlEscape="false"    class="form-control required"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label">所属部门:</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="office.name" readonly="readonly" class="form-control layui-input"  value="${workGoOut.office.topCompany}"/>
+                            <input type="hidden" name="office.id" readonly="readonly" class="form-control layui-input"  value="${workGoOut.office.id}"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请日期:</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="submitDate" readonly="readonly" class="form-control layui-input"
+                                   value="<fmt:formatDate value="${workGoOut.submitDate}" pattern="yyyy-MM-dd"/>"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm12 with-textarea">
+                        <label class="layui-form-label">说    明:</label>
+                        <div class="layui-input-block">
+                            <form:textarea path="remarks" htmlEscape="false" rows="3" maxlength="255" class="form-control"/>
+                        </div>
+                    </div>
+                </div>
+                <div class="form-group layui-row">
+                    <div class="form-group-label"><h2>附件信息</h2></div>
+                    <div class="layui-item nav-btns">
+                        <a id="attachment_btn" class="nav-btn nav-btn-add" title="添加附件"><i class="fa fa-plus"></i>&nbsp;添加附件</a>
+                    </div>
+                    <div id="addFile_attachment" style="display: none" class="upload-progress">
+                        <span id="fileName_attachment" ></span>
+                        <b><span id="baifenbi_attachment" ></span></b>
+                        <div class="progress">
+                            <div id="jindutiao_attachment" class="progress-bar" style="width: 0%" aria-valuenow="0">
+                            </div>
+                        </div>
+                    </div>
+                    <input id="attachment_file" type="file" name="attachment_file" multiple="multiple" style="display: none;" onChange="if(this.value)insertTitle(this.value);"/>
+                    <span id="attachment_title"></span>
+                    <div class="layui-item layui-col-xs12" style="padding:0 16px;">
+                        <table id="upTable" class="table table-bordered table-condensed details">
+                            <thead>
+                            <tr>
+                                    <%-- <th>序号</th>--%>
+                                <th>文件预览</th>
+                                <th>上传人</th>
+                                <th>上传时间</th>
+                                <th width="150px">操作</th>
+                            </tr>
+                            </thead>
+                            <tbody id="file_attachment">
+                            <c:forEach items="${workGoOut.workAttachments}" var = "workClientAttachment" varStatus="status">
+                                <tr>
+                                        <%-- <td>${status.index + 1}</td>--%>
+                                    <c:choose>
+                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                            <td><img src="${workClientAttachment.url}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.url}','90%','90%')" alt="${workClientAttachment.attachmentName}"></td>
+                                        </c:when>
+                                        <c:otherwise>
+                                            <c:choose>
+                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="preview('预览','${workClientAttachment.url}','90%','90%','1')">${workClientAttachment.attachmentName}</a></td>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="preview('预览','${workClientAttachment.url}','90%','90%')">${workClientAttachment.attachmentName}</a></td>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </c:otherwise>
+                                    </c:choose>
+                                    <td>${workClientAttachment.createBy.name}</td>
+                                    <td><fmt:formatDate value="${workClientAttachment.createDate}" type="both"/></td>
+                                    <td class="op-td">
+                                        <div class="op-btn-box" >
+                                            <a href="javascript:location.href='${ctx}/workfullmanage/workFullManage/downLoadAttach?file='+encodeURIComponent(encodeURIComponent('${workClientAttachment.url}'));" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+
+                                            <c:if test="${workClientAttachment.createBy.id eq fns:getUser().id}">
+                                                <a href="javascript:void(0)" onclick="deleteFileFromAliyun(this,'${ctx}/sys/workattachment/deleteFileFromAliyun?url=${workClientAttachment.url}&id=${workClientAttachment.id}&type=2','addFile')" class="op-btn op-btn-delete" ><i class="fa fa-trash"></i>&nbsp;删除</a>
+                                            </c:if>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:forEach>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+	        </form:form>
+        </div>
+    </div>
+</body>
+</html>

+ 15 - 0
src/main/webapp/webpage/modules/workgoout/workGoOutTask.jsp

@@ -0,0 +1,15 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<html>
+<head>
+	<title>流程追踪</title>
+	<meta name="decorator" content="default"/>
+</head>
+<body class="gray-bg">
+<div class="container form layui-form">
+	<act:flowChart procInsId="${processInstanceId}"/>
+	<act:histoicFlow procInsId="${processInstanceId}"/>
+</div>
+</body>
+</html>
+

+ 146 - 0
src/main/webapp/webpage/modules/workgoout/workGoOutView.jsp

@@ -0,0 +1,146 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<html>
+<head>
+	<title>外出管理</title>
+	<meta name="decorator" content="default"/>
+</head>
+<body>
+    <div class="single-form">
+        <div class="container view-form">
+            <form:form id="inputForm" modelAttribute="workGoOut" action="${ctx}/workgoout/workGoOut/save" method="post" class="form-horizontal">
+            <form:hidden path="id"/>
+                <div class="form-group layui-row first">
+                    <div class="form-group-label"><h2>基本信息</h2></div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label">外出类型:</label>
+                        <div class="layui-input-block">
+                            <input readonly="true" htmlEscape="false" class="form-control layui-input"
+                                   value="<c:choose><c:when test="${workGoOut.ext == 0}">项目外出</c:when><c:otherwise>非项目外出</c:otherwise></c:choose>"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label">项目名称:</label>
+                        <div class="layui-input-block">
+                            <form:input  path="project.projectName" htmlEscape="false" readonly="true" class="form-control  layui-input"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label">项目编号:</label>
+                        <div class="layui-input-block">
+                            <form:input  path="project.projectId" htmlEscape="false" readonly="true" class="form-control  layui-input"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请编号:</label>
+                        <div class="layui-input-block">
+                            <div class="input-group">
+                                <form:input path="num" htmlEscape="false"  readonly="true"  class="form-control  layui-input"/>
+                                <span class="input-group-btn">
+                                <label class="form-status"><c:choose><c:when test="${not empty workGoOut.state}">${fns:getDictLabel(workGoOut.state, 'audit_state', '')}</c:when><c:otherwise>新添</c:otherwise></c:choose></label>
+                             </span>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请人:</label>
+                        <div class="layui-input-block">
+                            <form:input path="submiter.name" htmlEscape="false" readonly="true" class="form-control layui-input required"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label">所属部门:</label>
+                        <div class="layui-input-block">
+                            <input type="text" name="office.name" readonly="readonly" class="form-control layui-input"  value="${workGoOut.office.topCompany}"/>
+                            <input type="hidden" name="office.id" readonly="readonly" class="form-control layui-input"  value="${workGoOut.office.id}"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm6">
+                        <label class="layui-form-label"><span class="require-item">*</span>申请日期:</label>
+                        <div class="layui-input-block">
+                            <input type="text" readonly="readonly" class="form-control layui-input"
+                                   value="<fmt:formatDate value="${workGoOut.submitDate}" pattern="yyyy-MM-dd"/>"/>
+                        </div>
+                    </div>
+                    <div class="layui-item layui-col-sm12 with-textarea">
+                        <label class="layui-form-label">说    明:</label>
+                        <div class="layui-input-block">
+                            <form:textarea path="remarks" readonly="true" htmlEscape="false" rows="3" class="form-control"/>
+                        </div>
+                    </div>
+                </div>
+                <div class="form-group layui-row">
+                    <div class="form-group-label"><h2>附件信息</h2></div>
+                    <div class="layui-item layui-col-xs12 form-table-container" >
+                        <table id="listAttachment" class="table table-bordered table-condensed no-bottom-margin details">
+                            <thead>
+                            <tr>
+                                    <%-- <th>序号</th>--%>
+                                <th>文件预览</th>
+                                <th>上传人</th>
+                                <th>上传时间</th>
+                                <th width="150px">操作</th>
+                            </tr>
+                            </thead>
+                            <tbody id="file_attachment">
+                            <c:forEach items="${workGoOut.workAttachments}" var = "workClientAttachment" varStatus="status">
+                                <tr>
+                                    <c:choose>
+                                        <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpg')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'png')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'gif')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'bmp')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jpeg')}">
+                                            <td><img src="${workClientAttachment.url}" width="50" height="50" onclick="openDialogView('预览','${ctx}/sys/picturepreview/picturePreview?url=${workClientAttachment.url}','90%','90%')" alt="${workClientAttachment.attachmentName}"></td>
+                                        </c:when>
+                                        <c:otherwise>
+                                            <c:choose>
+                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
+                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="preview('预览','${workClientAttachment.url}','90%','90%','1')">${workClientAttachment.attachmentName}</a></td>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="preview('预览','${workClientAttachment.url}','90%','90%')">${workClientAttachment.attachmentName}</a></td>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </c:otherwise>
+                                    </c:choose>
+                                    <td>${workClientAttachment.createBy.name}</td>
+                                    <td><fmt:formatDate value="${workClientAttachment.createDate}" type="both"/></td>
+                                    <td class="op-td">
+                                        <div class="op-btn-box" >
+                                            <c:set var="signflag" value="${fns:getSysParam('sign_flag',fns:getUser())}"/>
+                                            <c:choose>
+                                                <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'doc')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'docx')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'xls')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'xlsx')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'ppt')
+                                                           or fn:containsIgnoreCase(workClientAttachment.attachmentName,'pptx')}">
+                                                    <a href="javascript:void(0);" onclick="openDialogView('查看电子签章信息', '${ctx}/isignature/iSignatureDocument/form?recordId=${workClientAttachment.id}','95%', '95%')" class="op-btn op-btn-view" ><i class="fa fa-search-plus"></i> 查看</a>
+                                                    <c:choose>
+                                                        <c:when test="${signflag == '是'}">
+                                                            <a href="javascript:location.href='${ctx}/isignature/iSignatureDocument/download?recordId=${workClientAttachment.id}'" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                        </c:when>
+                                                        <c:otherwise>
+                                                            <a href="javascript:location.href='${ctx}/workfullmanage/workFullManage/downLoadAttach?file='+encodeURIComponent(encodeURIComponent('${workClientAttachment.url}'));" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                        </c:otherwise>
+                                                    </c:choose>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <a href="javascript:location.href='${ctx}/workfullmanage/workFullManage/downLoadAttach?file='+encodeURIComponent(encodeURIComponent('${workClientAttachment.url}'));" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:forEach>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+	        </form:form>
+        </div>
+    </div>
+</body>
+</html>

+ 2 - 2
src/main/webapp/webpage/modules/workinvoice/workInvoiceForm.jsp

@@ -393,7 +393,7 @@
 			</div>
 			<div class="form-group layui-row first lw14">
 				<div class="form-group-label"><h2>发票详情</h2></div>
-				<div class="layui-item layui-col-sm6">
+				<%--<div class="layui-item layui-col-sm6">
 					<label class="layui-form-label"><span class="require-item">*</span>上级/本公司开票:</label>
 					<div class="layui-input-block">
 						<c:choose>
@@ -415,7 +415,7 @@
 							</c:otherwise>
 						</c:choose>
 					</div>
-				</div>
+				</div>--%>
 				<div class="layui-item layui-col-sm6">
 					<label class="layui-form-label"><span class="require-item">*</span>发票类型:</label>
 					<div class="layui-input-block">

+ 2 - 2
src/main/webapp/webpage/modules/workinvoice/workInvoiceView.jsp

@@ -92,12 +92,12 @@
 			</div>
 			<div class="form-group layui-row first lw14">
 				<div class="form-group-label"><h2>发票详情</h2></div>
-				<div class="layui-item layui-col-sm6">
+				<%--<div class="layui-item layui-col-sm6">
 					<label class="layui-form-label"><span class="require-item">*</span>上级/本公司开票:</label>
 					<div class="layui-input-block">
 						<input htmlEscape="false" readonly="true"   class="form-control layui-input" value="<c:choose><c:when test="${workInvoice.ext eq '0'}">本公司开票	</c:when><c:when test="${workInvoice.ext eq '1'}">上级公司开票</c:when></c:choose>"/>
 					</div>
-				</div>
+				</div>--%>
 				<div class="layui-item layui-col-sm6">
 					<label class="layui-form-label"><span class="require-item">*</span>发票类型:</label>
 					<div class="layui-input-block">

+ 1 - 1
src/main/webapp/webpage/modules/workleave/workLeaveAudit.jsp

@@ -148,7 +148,7 @@
 					</div>
 				</div>
 				<div class="layui-item layui-col-sm6">
-					<label class="layui-form-label"><span class="require-item">*</span>用车情况:</label>
+					<label class="layui-form-label">用车情况:</label>
 					<div class="layui-input-block">
 						<form:input  path="car" htmlEscape="false" readonly="true"  class="form-control  layui-input"/>
 					</div>

+ 2 - 2
src/main/webapp/webpage/modules/workleave/workLeaveForm.jsp

@@ -204,9 +204,9 @@
 					</div>
 				</div>
 				<div class="layui-item layui-col-sm6 ">
-					<label class="layui-form-label"><span class="require-item">*</span>用车情况:</label>
+					<label class="layui-form-label">用车情况:</label>
 					<div class="layui-input-block">
-						<form:select path="car" class="form-control simple-select required" id="car">
+						<form:select path="car" class="form-control simple-select" id="car">
 							<form:option value="" label="--请选择用车类型--"/>
                             <form:options items="${fns:getMainDictList('card_type')}" itemLabel="label" itemValue="value" htmlEscape="false"/>
 						</form:select>

+ 2 - 2
src/main/webapp/webpage/modules/workleave/workLeaveModify.jsp

@@ -195,9 +195,9 @@
 					</div>
 				</div>
 				<div class="layui-item layui-col-sm6 ">
-					<label class="layui-form-label"><span class="require-item">*</span>用车情况:</label>
+					<label class="layui-form-label">用车情况:</label>
 					<div class="layui-input-block">
-						<form:select path="car" cssClass="form-control required simple-select">
+						<form:select path="car" cssClass="form-control simple-select">
 							<form:option value="" label=""/>
 							<form:options items="${fns:getMainDictList('card_type')}" itemLabel="label" itemValue="value" htmlEscape="false"/>
 						</form:select>

+ 2 - 2
src/main/webapp/webpage/modules/workleave/workLeaveView.jsp

@@ -140,9 +140,9 @@
                     </div>
                 </div>
                 <div class="layui-item layui-col-sm6">
-                    <label class="layui-form-label"><span class="require-item">*</span>用车情况:</label>
+                    <label class="layui-form-label">用车情况:</label>
                     <div class="layui-input-block">
-                        <form:input  path="car" htmlEscape="false" readonly="true"  class="form-control required layui-input"/>
+                        <form:input  path="car" htmlEscape="false" readonly="true"  class="form-control layui-input"/>
                     </div>
                 </div>
                 <div class="layui-item layui-col-sm6">