Procházet zdrojové kódy

子项目压缩包上传处理

user5 před 4 roky
rodič
revize
f678bb29af
17 změnil soubory, kde provedl 4343 přidání a 0 odebrání
  1. 19 0
      pom.xml
  2. 27 0
      src/main/java/com/jeeplus/modules/ruralprojectrecords/dao/SubProjectInfoDao.java
  3. 501 0
      src/main/java/com/jeeplus/modules/ruralprojectrecords/entity/SubProjectInfo.java
  4. 688 0
      src/main/java/com/jeeplus/modules/ruralprojectrecords/service/SubProjectInfoService.java
  5. 233 0
      src/main/java/com/jeeplus/modules/ruralprojectrecords/utils/ImportExcelUtil.java
  6. 201 0
      src/main/java/com/jeeplus/modules/ruralprojectrecords/web/SubProjectInfoController.java
  7. 7 0
      src/main/java/com/jeeplus/modules/sys/dao/WorkattachmentDao.java
  8. 347 0
      src/main/resources/mappings/modules/ruralprojectrecords/SubProjectInfoDao.xml
  9. 5 0
      src/main/resources/mappings/modules/sys/WorkattachmentDao.xml
  10. 15 0
      src/main/webapp/WEB-INF/tags/table/subProjectAddRow.tag
  11. binární
      src/main/webapp/static/images/filePhoto.jpg
  12. 6 0
      src/main/webapp/webpage/modules/ruralprojectrecords/cost/ruralCostProjectRecordsView.jsp
  13. 6 0
      src/main/webapp/webpage/modules/ruralprojectrecords/ruralProjectRecordsView.jsp
  14. 514 0
      src/main/webapp/webpage/modules/ruralprojectrecords/subProjectInfo/subProjectFileForm.jsp
  15. 782 0
      src/main/webapp/webpage/modules/ruralprojectrecords/subProjectInfo/subProjectInfoForm.jsp
  16. 384 0
      src/main/webapp/webpage/modules/ruralprojectrecords/subProjectInfo/subProjectInfoList.jsp
  17. 608 0
      src/main/webapp/webpage/modules/ruralprojectrecords/subProjectInfo/subProjectInfoView.jsp

+ 19 - 0
pom.xml

@@ -1006,6 +1006,25 @@
             <artifactId>cxf-rt-transports-http</artifactId>
             <version>3.1.10</version>
         </dependency>
+
+        <!-- 解压7z -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+            <version>1.9</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.tukaani</groupId>
+            <artifactId>xz</artifactId>
+            <version>1.5</version>
+        </dependency>
+        <!-- 解压rar -->
+        <dependency>
+            <groupId>com.github.junrar</groupId>
+            <artifactId>junrar</artifactId>
+            <version>0.7</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 27 - 0
src/main/java/com/jeeplus/modules/ruralprojectrecords/dao/SubProjectInfoDao.java

@@ -0,0 +1,27 @@
+package com.jeeplus.modules.ruralprojectrecords.dao;
+
+import com.jeeplus.common.persistence.CrudDao;
+import com.jeeplus.common.persistence.annotation.MyBatisDao;
+import com.jeeplus.modules.ruralprojectrecords.entity.SubProjectInfo;
+
+/**
+ * 子项目dao
+ * @author: 徐滕
+ * @create: 2021-01-14 10:33
+ **/
+@MyBatisDao
+public interface SubProjectInfoDao extends CrudDao<SubProjectInfo> {
+
+    /**
+     * 查询项目定义号是否已存在
+     * @param subProjectInfo
+     * @return
+     */
+    SubProjectInfo decideRepeat(SubProjectInfo subProjectInfo);
+
+    /**
+     * 删除所有父项目的子项目
+     * @param parentProId
+     */
+    void deleteByParentProId(String parentProId);
+}

+ 501 - 0
src/main/java/com/jeeplus/modules/ruralprojectrecords/entity/SubProjectInfo.java

@@ -0,0 +1,501 @@
+package com.jeeplus.modules.ruralprojectrecords.entity;
+
+import com.jeeplus.common.persistence.DataEntity;
+import com.jeeplus.modules.sys.entity.Office;
+import com.jeeplus.modules.sys.entity.Workattachment;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 子项目实体类
+ * @author: 大猫
+ * @create: 2021-01-14 10:01
+ **/
+public class SubProjectInfo extends DataEntity<SubProjectInfo> {
+
+    private static final long serialVersionUID = 1L;
+    private String projectId;//主键,项目定义号
+    private String parentProId;//父项目id
+    private String projectName;//项目名称
+    private String wbsNum;//单体工程wbs编号
+    private String programmeId;//工程编号
+    private String programmeName;//工程名称
+    private String auditItemsType;//审计项目类型
+    private String voltageLevel;//电压等级
+    private String onSiteContact;//现场联系人
+    private String contactNumber;//联系电话
+    private Date actualStartTime;//实际开工时间
+    private Date actualEndTime;//实际竣工时间
+    private String constructionUnit;//施工单位名称
+    private String contractId;//合同编号
+    private Double contractSum;//合同金额
+    private Date planStartTime;//计划开工时间
+    private Date planEndTime;//计划竣工时间
+    private Double settleDiscountRate;//结算折扣率
+    private Double civilSubmitSum;//土建结算送审金额(元)下浮后金额
+    private Double installSubmitSum;//安装结算送审金额(元)下浮后金额
+    private Double buildSubmitSum;//施工费送审金额小计(元)下浮后金额
+    private Double materialSubmitSum;//甲供材送审金额(元)结算书中的物资金额
+    private Double civilAuthorizeSum;//土建结算审定金额(元)下浮后金额
+    private Double installAuthorizeSum;//安装结算审定金额(元)下浮后金额
+    private Double buildAuthorizeSum;//施工费审定金额小计(元)下浮后金额
+    private Double materialAuthorizeSum;//甲供材审定金额(元)
+    private Double buildDiscountSum;//施工费核减金额(元)
+    private Double buildDiscountRate;//施工费核减率(%)
+    private Double creditDeduction;//施工单位诚信扣款(元)
+    private Double suggestedSettlement;//建议结算款(元)
+    private String hasViewScene;//是否查看现场(必填),填是或者否
+    private Double auditFee;//审计费(元)
+    private String optionNum;//审计部下发意见文号
+    private String officeReportNo;//事务所审计报告号(必填)
+    private String officeName;//事务所名称
+    private String officeAuditor;//事务所审计人员
+    private Date packTime;//打包时间
+    private Date planAuditTime;//审计应结束时间
+    private String auditType;//审计方式
+    private String remarks;//备注
+    private String auditProfessional;//审计专职
+    private Date submitApprovalTime;//提交送审日期
+    private String submitApprovalMan;//送审人
+    private String submitApprovalDepartment;//送审部门
+    private String secondaryUnit;//二级单位
+    private String firstLevelUnit;//一级单位
+    private String submissionFormId;//送审单ID(勿动)
+    private List<Workattachment> workAttachments;  //附件信息
+
+    private Date beginDate;//打包开始时间
+    private Date endDate;//打包结束时间
+
+    private Office office;
+    private Office company;
+
+    private String projectType;//父项目类型
+
+    public String getProjectId() {
+        return projectId;
+    }
+
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
+    }
+
+    public String getParentProId() {
+        return parentProId;
+    }
+
+    public void setParentProId(String parentProId) {
+        this.parentProId = parentProId;
+    }
+
+    public String getProjectName() {
+        return projectName;
+    }
+
+    public void setProjectName(String projectName) {
+        this.projectName = projectName;
+    }
+
+    public String getWbsNum() {
+        return wbsNum;
+    }
+
+    public void setWbsNum(String wbsNum) {
+        this.wbsNum = wbsNum;
+    }
+
+    public String getProgrammeId() {
+        return programmeId;
+    }
+
+    public void setProgrammeId(String programmeId) {
+        this.programmeId = programmeId;
+    }
+
+    public String getProgrammeName() {
+        return programmeName;
+    }
+
+    public void setProgrammeName(String programmeName) {
+        this.programmeName = programmeName;
+    }
+
+    public String getAuditItemsType() {
+        return auditItemsType;
+    }
+
+    public void setAuditItemsType(String auditItemsType) {
+        this.auditItemsType = auditItemsType;
+    }
+
+    public String getVoltageLevel() {
+        return voltageLevel;
+    }
+
+    public void setVoltageLevel(String voltageLevel) {
+        this.voltageLevel = voltageLevel;
+    }
+
+    public String getOnSiteContact() {
+        return onSiteContact;
+    }
+
+    public void setOnSiteContact(String onSiteContact) {
+        this.onSiteContact = onSiteContact;
+    }
+
+    public String getContactNumber() {
+        return contactNumber;
+    }
+
+    public void setContactNumber(String contactNumber) {
+        this.contactNumber = contactNumber;
+    }
+
+    public Date getActualStartTime() {
+        return actualStartTime;
+    }
+
+    public void setActualStartTime(Date actualStartTime) {
+        this.actualStartTime = actualStartTime;
+    }
+
+    public Date getActualEndTime() {
+        return actualEndTime;
+    }
+
+    public void setActualEndTime(Date actualEndTime) {
+        this.actualEndTime = actualEndTime;
+    }
+
+    public String getConstructionUnit() {
+        return constructionUnit;
+    }
+
+    public void setConstructionUnit(String constructionUnit) {
+        this.constructionUnit = constructionUnit;
+    }
+
+    public String getContractId() {
+        return contractId;
+    }
+
+    public void setContractId(String contractId) {
+        this.contractId = contractId;
+    }
+
+    public Double getContractSum() {
+        return contractSum;
+    }
+
+    public void setContractSum(Double contractSum) {
+        this.contractSum = contractSum;
+    }
+
+    public Date getPlanStartTime() {
+        return planStartTime;
+    }
+
+    public void setPlanStartTime(Date planStartTime) {
+        this.planStartTime = planStartTime;
+    }
+
+    public Date getPlanEndTime() {
+        return planEndTime;
+    }
+
+    public void setPlanEndTime(Date planEndTime) {
+        this.planEndTime = planEndTime;
+    }
+
+    public Double getSettleDiscountRate() {
+        return settleDiscountRate;
+    }
+
+    public void setSettleDiscountRate(Double settleDiscountRate) {
+        this.settleDiscountRate = settleDiscountRate;
+    }
+
+    public Double getCivilSubmitSum() {
+        return civilSubmitSum;
+    }
+
+    public void setCivilSubmitSum(Double civilSubmitSum) {
+        this.civilSubmitSum = civilSubmitSum;
+    }
+
+    public Double getInstallSubmitSum() {
+        return installSubmitSum;
+    }
+
+    public void setInstallSubmitSum(Double installSubmitSum) {
+        this.installSubmitSum = installSubmitSum;
+    }
+
+    public Double getBuildSubmitSum() {
+        return buildSubmitSum;
+    }
+
+    public void setBuildSubmitSum(Double buildSubmitSum) {
+        this.buildSubmitSum = buildSubmitSum;
+    }
+
+    public Double getMaterialSubmitSum() {
+        return materialSubmitSum;
+    }
+
+    public void setMaterialSubmitSum(Double materialSubmitSum) {
+        this.materialSubmitSum = materialSubmitSum;
+    }
+
+    public Double getCivilAuthorizeSum() {
+        return civilAuthorizeSum;
+    }
+
+    public void setCivilAuthorizeSum(Double civilAuthorizeSum) {
+        this.civilAuthorizeSum = civilAuthorizeSum;
+    }
+
+    public Double getInstallAuthorizeSum() {
+        return installAuthorizeSum;
+    }
+
+    public void setInstallAuthorizeSum(Double installAuthorizeSum) {
+        this.installAuthorizeSum = installAuthorizeSum;
+    }
+
+    public Double getBuildAuthorizeSum() {
+        return buildAuthorizeSum;
+    }
+
+    public void setBuildAuthorizeSum(Double buildAuthorizeSum) {
+        this.buildAuthorizeSum = buildAuthorizeSum;
+    }
+
+    public Double getMaterialAuthorizeSum() {
+        return materialAuthorizeSum;
+    }
+
+    public void setMaterialAuthorizeSum(Double materialAuthorizeSum) {
+        this.materialAuthorizeSum = materialAuthorizeSum;
+    }
+
+    public Double getBuildDiscountSum() {
+        return buildDiscountSum;
+    }
+
+    public void setBuildDiscountSum(Double buildDiscountSum) {
+        this.buildDiscountSum = buildDiscountSum;
+    }
+
+    public Double getBuildDiscountRate() {
+        return buildDiscountRate;
+    }
+
+    public void setBuildDiscountRate(Double buildDiscountRate) {
+        this.buildDiscountRate = buildDiscountRate;
+    }
+
+    public Double getCreditDeduction() {
+        return creditDeduction;
+    }
+
+    public void setCreditDeduction(Double creditDeduction) {
+        this.creditDeduction = creditDeduction;
+    }
+
+    public Double getSuggestedSettlement() {
+        return suggestedSettlement;
+    }
+
+    public void setSuggestedSettlement(Double suggestedSettlement) {
+        this.suggestedSettlement = suggestedSettlement;
+    }
+
+    public String getHasViewScene() {
+        return hasViewScene;
+    }
+
+    public void setHasViewScene(String hasViewScene) {
+        this.hasViewScene = hasViewScene;
+    }
+
+    public Double getAuditFee() {
+        return auditFee;
+    }
+
+    public void setAuditFee(Double auditFee) {
+        this.auditFee = auditFee;
+    }
+
+    public String getOptionNum() {
+        return optionNum;
+    }
+
+    public void setOptionNum(String optionNum) {
+        this.optionNum = optionNum;
+    }
+
+    public String getOfficeReportNo() {
+        return officeReportNo;
+    }
+
+    public void setOfficeReportNo(String officeReportNo) {
+        this.officeReportNo = officeReportNo;
+    }
+
+    public String getOfficeName() {
+        return officeName;
+    }
+
+    public void setOfficeName(String officeName) {
+        this.officeName = officeName;
+    }
+
+    public String getOfficeAuditor() {
+        return officeAuditor;
+    }
+
+    public void setOfficeAuditor(String officeAuditor) {
+        this.officeAuditor = officeAuditor;
+    }
+
+    public Date getPackTime() {
+        return packTime;
+    }
+
+    public void setPackTime(Date packTime) {
+        this.packTime = packTime;
+    }
+
+    public Date getPlanAuditTime() {
+        return planAuditTime;
+    }
+
+    public void setPlanAuditTime(Date planAuditTime) {
+        this.planAuditTime = planAuditTime;
+    }
+
+    public String getAuditType() {
+        return auditType;
+    }
+
+    public void setAuditType(String auditType) {
+        this.auditType = auditType;
+    }
+
+    @Override
+    public String getRemarks() {
+        return remarks;
+    }
+
+    @Override
+    public void setRemarks(String remarks) {
+        this.remarks = remarks;
+    }
+
+    public String getAuditProfessional() {
+        return auditProfessional;
+    }
+
+    public void setAuditProfessional(String auditProfessional) {
+        this.auditProfessional = auditProfessional;
+    }
+
+    public Date getSubmitApprovalTime() {
+        return submitApprovalTime;
+    }
+
+    public void setSubmitApprovalTime(Date submitApprovalTime) {
+        this.submitApprovalTime = submitApprovalTime;
+    }
+
+    public String getSubmitApprovalMan() {
+        return submitApprovalMan;
+    }
+
+    public void setSubmitApprovalMan(String submitApprovalMan) {
+        this.submitApprovalMan = submitApprovalMan;
+    }
+
+    public String getSubmitApprovalDepartment() {
+        return submitApprovalDepartment;
+    }
+
+    public void setSubmitApprovalDepartment(String submitApprovalDepartment) {
+        this.submitApprovalDepartment = submitApprovalDepartment;
+    }
+
+    public String getSecondaryUnit() {
+        return secondaryUnit;
+    }
+
+    public void setSecondaryUnit(String secondaryUnit) {
+        this.secondaryUnit = secondaryUnit;
+    }
+
+    public String getFirstLevelUnit() {
+        return firstLevelUnit;
+    }
+
+    public void setFirstLevelUnit(String firstLevelUnit) {
+        this.firstLevelUnit = firstLevelUnit;
+    }
+
+    public String getSubmissionFormId() {
+        return submissionFormId;
+    }
+
+    public void setSubmissionFormId(String submissionFormId) {
+        this.submissionFormId = submissionFormId;
+    }
+
+    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 getProjectType() {
+        return projectType;
+    }
+
+    public void setProjectType(String projectType) {
+        this.projectType = projectType;
+    }
+
+    public Office getOffice() {
+        return office;
+    }
+
+    public void setOffice(Office office) {
+        this.office = office;
+    }
+
+    public Office getCompany() {
+        return company;
+    }
+
+    public void setCompany(Office company) {
+        this.company = company;
+    }
+
+    public List<Workattachment> getWorkAttachments() {
+        return workAttachments;
+    }
+
+    public void setWorkAttachments(List<Workattachment> workAttachments) {
+        this.workAttachments = workAttachments;
+    }
+}

+ 688 - 0
src/main/java/com/jeeplus/modules/ruralprojectrecords/service/SubProjectInfoService.java

@@ -0,0 +1,688 @@
+package com.jeeplus.modules.ruralprojectrecords.service;
+
+import com.alibaba.fastjson.JSON;
+import com.github.junrar.Archive;
+import com.github.junrar.exception.RarException;
+import com.github.junrar.rarfile.FileHeader;
+import com.google.common.collect.Lists;
+import com.jeeplus.common.bos.BOSClientUtil;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.MenuStatusEnum;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.utils.excel.ImportExcel;
+import com.jeeplus.modules.ruralprojectrecords.dao.SubProjectInfoDao;
+import com.jeeplus.modules.ruralprojectrecords.entity.SubProjectInfo;
+import com.jeeplus.modules.ruralprojectrecords.utils.ImportExcelUtil;
+import com.jeeplus.modules.sys.dao.WorkattachmentDao;
+import com.jeeplus.modules.sys.entity.Workattachment;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
+import org.apache.commons.io.FilenameUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.net.URI;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import org.apache.commons.compress.archivers.sevenz.SevenZFile;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+/**
+ * 子项目service
+ * @author: 徐滕
+ * @create: 2021-01-14 10:32
+ **/
+@Service
+@Transactional(readOnly = true)
+public class SubProjectInfoService extends CrudService<SubProjectInfoDao, SubProjectInfo> {
+    @Autowired
+    private WorkattachmentDao workattachmentDao;
+
+    public SubProjectInfo get(String id) {
+        return super.get(id);
+    }
+
+    /**
+     * 获取子项目数据信息集合
+     * @param page 分页对象
+     * @param subProjectInfo
+     * @return
+     */
+    public Page<SubProjectInfo> findPage(Page<SubProjectInfo> page, SubProjectInfo subProjectInfo) {
+        //设置数据权限
+        if(!UserUtils.getUser().isAdmin()) {
+            String dataScopeSql = null;
+            //判断查询为工程咨询信息
+            if("1".equals(subProjectInfo.getProjectType())){
+                dataScopeSql = dataScopeFilter(subProjectInfo.getCurrentUser(), "o", "u", "s", MenuStatusEnum.OVERALL_WORK_RECORDS.getValue());
+            } else if("2".equals(subProjectInfo.getProjectType())){//判断查询为造价审核信息
+                dataScopeSql = dataScopeFilter(subProjectInfo.getCurrentUser(), "o", "u", "s", MenuStatusEnum.OVERALL_COST_WORK_RECORDS.getValue());
+            }else{
+                dataScopeSql = dataScopeFilter(subProjectInfo.getCurrentUser(), "o", "u", "s", MenuStatusEnum.OVERALL_WORK_RECORDS.getValue());
+            }
+            subProjectInfo.getSqlMap().put("dsf", dataScopeSql);
+        }
+        int count = dao.queryCount(subProjectInfo);
+        page.setCount(count);
+        page.setCountFlag(false);
+        subProjectInfo.setPage(page);
+        List<SubProjectInfo> recordsList = findList(subProjectInfo);
+
+        for (SubProjectInfo info: recordsList) {
+            info.setProjectType(subProjectInfo.getProjectType());
+        }
+
+        page.setList(recordsList);
+        return page;
+    }
+
+    /**
+     * 查询集合方法
+     * @param subProjectInfo
+     * @return
+     */
+    public List<SubProjectInfo> findList(SubProjectInfo subProjectInfo) {
+        return super.findList(subProjectInfo);
+    }
+
+    /**
+     * 查询项目定义号是否已存在
+     * @param subProjectInfo
+     * @return
+     */
+    public SubProjectInfo decideRepeat(SubProjectInfo subProjectInfo){
+        return dao.decideRepeat(subProjectInfo);
+    }
+
+    /**
+     * 新增 修改
+     * @param subProjectInfo
+     */
+    @Transactional(readOnly = false)
+    public void save(SubProjectInfo subProjectInfo){
+        subProjectInfo.setOffice(UserUtils.getSelectOffice());
+        subProjectInfo.setCompany(UserUtils.getSelectCompany());
+        super.save(subProjectInfo);
+        List<Workattachment> attachmentList = subProjectInfo.getWorkAttachments();
+        //保存附件+tree
+        if (attachmentList!=null && attachmentList.size()!=0) {
+            //附件信息
+            for (Workattachment workattachment : attachmentList) {
+                if ("86".equals(workattachment.getAttachmentFlag())){
+                    workattachment.setDivIdType("_subAttachment");
+                } else if ("152".equals(workattachment.getAttachmentFlag())){
+                    workattachment.setDivIdType("_subGistdata");
+                }else if ("153".equals(workattachment.getAttachmentFlag())){
+                    workattachment.setDivIdType("_subOther");
+                }
+                if (workattachment.getId() == null) {
+                    continue;
+                }
+                if (workattachment.DEL_FLAG_NORMAL.equals(workattachment.getDelFlag())) {
+                    workattachment.setAttachmentId(subProjectInfo.getId());
+                    workattachment.setAttachmentUser(UserUtils.getUser().getId());
+                    if (com.jeeplus.common.utils.StringUtils.isBlank(workattachment.getId()) || "null".equals(workattachment.getId())) {
+                        workattachment.preInsert();
+                        if (null == workattachment.getDivIdType()){
+                            workattachment.setDivIdType("");
+                        }
+                        //新增
+                        workattachment.preInsert();
+                        workattachmentDao.insert(workattachment);
+                    } else {
+                        //修改
+                        workattachment.preUpdate();
+                        workattachmentDao.update(workattachment);
+                    }
+                } else {
+                    //删除
+                    workattachmentDao.delete(workattachment);
+                }
+            }
+        }
+    }
+    /**
+     * 新增 修改
+     * @param subProjectInfo
+     */
+    @Transactional(readOnly = false)
+    public void saveWorkattachment(SubProjectInfo subProjectInfo){
+        List<Workattachment> attachmentList = subProjectInfo.getWorkAttachments();
+        //保存附件+tree
+        if (attachmentList!=null && attachmentList.size()!=0) {
+            //附件信息
+            for (Workattachment workattachment : attachmentList) {
+                if (workattachment.DEL_FLAG_NORMAL.equals(workattachment.getDelFlag())) {
+                    workattachment.setAttachmentUser(UserUtils.getUser().getId());
+                    if (com.jeeplus.common.utils.StringUtils.isBlank(workattachment.getId()) || "null".equals(workattachment.getId())) {
+                        //新增
+                        workattachment.preInsert();
+                        workattachmentDao.insert(workattachment);
+                    } else {
+                        //修改
+                        workattachment.preUpdate();
+                        workattachmentDao.update(workattachment);
+                    }
+                } else {
+                    //删除
+                    workattachmentDao.delete(workattachment);
+                }
+            }
+        }
+    }
+
+    /**
+     * 查询附件信息
+     * @param subProjectInfo
+     */
+    public void getWorkattachmentList(SubProjectInfo subProjectInfo){
+        Workattachment workattachment = new Workattachment();
+        workattachment.setAttachmentId(subProjectInfo.getId());
+        //查询附件信息并添加
+        subProjectInfo.setWorkAttachments(workattachmentDao.findList(workattachment));
+    }
+
+    /**
+     * 压缩文件处理
+     * @param subProjectInfo
+     * @param file
+     * @throws IllegalStateException
+     * @throws IOException
+     */
+    @Transactional(readOnly = false)
+    public Integer compressFileManage(SubProjectInfo subProjectInfo, MultipartFile file) throws IllegalStateException, IOException {
+        //MultipartFile转File
+        File srcFile = transformMultipartFile(file);
+        //获取文件暂存路径
+        String destDirPath= null;
+        if(System.getProperty("os.name").toLowerCase().contains("win")){
+            destDirPath = Global.getConfig("windowsPath")+"/temporaryFile";
+        }else{
+            destDirPath = Global.getConfig("linuxPath")+"/temporaryFile";
+        }
+        // 判断源文件是否存在
+        if (!srcFile.exists()) {
+            throw new RuntimeException(srcFile.getPath() + "所指文件不存在");
+        }
+        //获取文件的后缀名
+        String fileName = srcFile.getName();
+        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
+        //根据文件后缀进行解压缩
+        switch (suffix){
+            case "zip" :
+                unZipFile(srcFile,destDirPath);
+                break;
+            case "7z" :
+                un7zFile(srcFile,destDirPath);
+                break;
+            case "rar" :
+                realExtract(srcFile,destDirPath,"C:\\Program Files\\WinRAR\\WinRAR.exe");
+                break;
+        }
+        //对压缩文件进行处理并返回
+        return this.subProjectFileManage(subProjectInfo,destDirPath);
+    }
+
+    /**
+     * 根据父项目信息和压缩文件解压路径进行数据处理
+     * @param subProjectInfo
+     * @param destDirPath
+     */
+    @Transactional(readOnly = false)
+    public Integer subProjectFileManage(SubProjectInfo subProjectInfo,String destDirPath){
+        Integer result = 0;
+        try {
+            File file = new File(destDirPath);
+            File[] files = file.listFiles();
+            Arrays.sort(files);
+            if(files.length > 1){
+                for (int i = 0; i<files.length;i++){
+                    if (files[i].isFile()){
+                        InputStreamReader reader = null;
+                        reader = new InputStreamReader(new FileInputStream(files[i]));
+                        BufferedReader bufferedReader = new BufferedReader(reader);
+                        String line = "";
+                        line = bufferedReader.readLine();
+                        while (line != null){
+                            System.out.println(files[i].getName()+":"+line);
+                            line = bufferedReader.readLine();
+                        }
+                        bufferedReader.close();
+                    }
+                }
+            }else{
+                while (files.length == 1){
+                    files = getFiles(files[0].toURI());
+                }
+                for (File fileInfo: files) {
+                    //判断fileInfo是文件而不是文件夹
+                    if(fileInfo.isFile()){
+                        //获取文件的后缀名
+                        String fileName = fileInfo.getName();
+                        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
+                        //判断文件是否为excel文件并且文件名包含“项目审计审定数据”
+                        if(StringUtils.isNotBlank(suffix) && ("xls".equals(suffix) || "xlsx".equals(suffix)) && fileName.contains("项目审计审定数据")){
+                            FileInputStream fis = new FileInputStream(fileInfo);
+                            List<Map<String, Object>> mapList = ImportExcelUtil.parseExcel(fis, fileInfo.getName(), ImportExcelUtil.mapInfo(),0);
+                            if(null != mapList){
+                                for (Map mapInfo:mapList) {
+                                    //map转实体类
+                                    SubProjectInfo subProject = JSON.parseObject(JSON.toJSONString(mapInfo), SubProjectInfo.class);
+                                    //添加父项目id
+                                    subProject.setParentProId(subProjectInfo.getParentProId());
+                                    //根据项目定义号查询项目
+                                    SubProjectInfo decideRepeatInfo = dao.decideRepeat(subProject);
+                                    if(null != decideRepeatInfo){
+                                        subProject.setId(decideRepeatInfo.getId());
+                                        //删除原有项目的所有附件信息
+                                        workattachmentDao.deleteByAttachmentId(decideRepeatInfo.getId());
+                                    }
+                                    //进行新增操作
+                                    this.save(subProject);
+                                    //处理附件信息
+                                    this.disposeAccessory(files,subProject);
+                                    if(null != subProject.getWorkAttachments()){
+                                        //添加附件信息
+                                        this.saveWorkattachment(subProject);
+                                    }
+                                    result ++;
+                                }
+                            }
+                        }
+                    }
+                }
+                deleteAllFilesOfDir(file);
+            }
+
+        }  catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    /**
+     * 删除解压文件
+     * @param path
+     */
+    public static void deleteAllFilesOfDir(File path) {
+        if (!path.exists())
+            return;
+        if (path.isFile()) {
+            path.delete();
+            return;
+        }
+        File[] files = path.listFiles();
+        for (int i = 0; i < files.length; i++) {
+            deleteAllFilesOfDir(files[i]);
+        }
+        path.delete();
+    }
+
+    public void disposeAccessory(File[] files,SubProjectInfo subProjectInfo){
+        List<Workattachment> workAttachments = Lists.newArrayList();
+        //再次遍历
+        for (File fileInfo: files) {
+            //判断fileInfo是文件夹而不是文件
+            if(fileInfo.isDirectory()){
+                //获取文件的后缀名
+                String fileName = fileInfo.getName();
+                //获取对应文件名
+                String suffix = subProjectInfo.getProjectName()+"-"+subProjectInfo.getProgrammeId();
+                //判断是否为当前项目的对应文件夹
+                if(StringUtils.isNotBlank(suffix) && fileName.equals(suffix)){
+                    File[] fileList = getFiles(fileInfo.toURI());
+                    for (File file: fileList) {
+                        //创建附件信息
+                        if(file.isDirectory() && "成果文件".equals(file.getName())){
+                            File[] attachmentList = getFiles(file.toURI());
+                            for (File attachment: attachmentList) {
+                                if(attachment.isFile()){
+                                    String uploadUrl = uploadUrl(transformFile(attachment));
+                                    Workattachment work = new Workattachment();
+                                    work.setUrl(uploadUrl);
+                                    work.setDivIdType("_subAttachment");
+                                    work.setAttachmentName(attachment.getName());
+                                    work.setDelFlag("0");
+                                    work.setAttachmentId(subProjectInfo.getId());
+                                    workAttachments.add(work);
+                                }
+                            }
+                            subProjectInfo.setWorkAttachments(workAttachments);
+                        }else if(file.isDirectory() && "依据性文件".equals(file.getName())){
+                            File[] attachmentList = getFiles(file.toURI());
+                            for (File attachment: attachmentList) {
+                                if(attachment.isFile()){
+                                    String uploadUrl = uploadUrl(transformFile(attachment));
+                                    Workattachment work = new Workattachment();
+                                    work.setUrl(uploadUrl);
+                                    work.setDivIdType("_subGistdata");
+                                    work.setAttachmentName(attachment.getName());
+                                    work.setDelFlag("0");
+                                    work.setAttachmentId(subProjectInfo.getId());
+                                    workAttachments.add(work);
+                                }
+                            }
+                            subProjectInfo.setWorkAttachments(workAttachments);
+                        }else if(file.isDirectory() && "其他文件".equals(file.getName())){
+                            File[] attachmentList = getFiles(file.toURI());
+                            for (File attachment: attachmentList) {
+                                if(attachment.isFile()){
+                                    String uploadUrl = uploadUrl(transformFile(attachment));
+                                    Workattachment work = new Workattachment();
+                                    work.setUrl(uploadUrl);
+                                    work.setDivIdType("_subOther");
+                                    work.setAttachmentName(attachment.getName());
+                                    work.setDelFlag("0");
+                                    work.setAttachmentId(subProjectInfo.getId());
+                                    workAttachments.add(work);
+                                }
+                            }
+                            subProjectInfo.setWorkAttachments(workAttachments);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 附件上传
+     * @param file
+     * @return
+     */
+    public static String uploadUrl(MultipartFile file){
+        String path = "/"+"newxgccpm-test/attachment-file/basedData/" + new Date().getTime() + "/" + file.getName();
+        BOSClientUtil bosClientUtil = new BOSClientUtil();
+        InputStream inputStream = null;
+        try {
+            inputStream = file.getInputStream();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        String uploadUrl = bosClientUtil.upload(path, inputStream);
+        return uploadUrl;
+    }
+
+    /**
+     * 根据地址获取File文件
+     * @param destDirPath
+     * @return
+     */
+    public static File[] getFiles(URI destDirPath){
+        File file = new File(destDirPath);
+        File[] files = file.listFiles();
+        return files;
+    }
+
+    /**
+     * 获取流文件
+     * @param ins
+     * @param file
+     */
+    public static void inputStreamToFile(InputStream ins, File file) {
+        try {
+            OutputStream os = new FileOutputStream(file);
+            int bytesRead = 0;
+            byte[] buffer = new byte[8192];
+            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.close();
+            ins.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * File转MultipartFile
+     * @param file
+     * @return
+     */
+    public static MultipartFile transformFile(File file){
+        InputStream inputStream = null;
+        MultipartFile multipartFile = null;
+        try {
+            inputStream = new FileInputStream(file);
+        multipartFile = new MockMultipartFile(file.getName(), inputStream);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return multipartFile;
+    }
+
+    /**
+     * MultipartFile转File
+     * @param file
+     * @return
+     * @throws IOException
+     */
+    public static File transformMultipartFile( MultipartFile file) throws IOException {
+        File srcFile = null;
+        //MultipartFile转File
+        if (file.equals("") || file.getSize() <= 0) {
+            file = null;
+        } else {
+            InputStream ins = null;
+            ins = file.getInputStream();
+            srcFile = new File(file.getOriginalFilename());
+            inputStreamToFile(ins, srcFile);
+            ins.close();
+        }
+        return srcFile;
+    }
+
+    /**
+     * zip文件解压
+     * @param file
+     */
+    public static void unZipFile(File file,String destDirPath){
+        // 开始解压
+        ZipFile zipFile = null;
+        try {
+            zipFile = new ZipFile(file);
+            Enumeration<?> entries = zipFile.entries();
+            while (entries.hasMoreElements()) {
+                ZipEntry entry = (ZipEntry) entries.nextElement();
+                System.out.println("解压" + entry.getName());
+                // 如果是文件夹,就创建个文件夹
+                if (entry.isDirectory()) {
+                    String dirPath = destDirPath + "/" + entry.getName();
+                    File dir = new File(dirPath);
+                    dir.mkdirs();
+                } else {
+                    // 如果是文件,就先创建一个文件,然后用io流把内容copy过去
+                    File targetFile = new File(destDirPath + "/" + entry.getName());
+                    // 保证这个文件的父文件夹必须要存在
+                    if(!targetFile.getParentFile().exists()){
+                        targetFile.getParentFile().mkdirs();
+                    }
+                    targetFile.createNewFile();
+                    // 将压缩文件内容写入到这个文件中
+                    InputStream is = zipFile.getInputStream(entry);
+                    FileOutputStream fos = new FileOutputStream(targetFile);
+                    int len;
+                    byte[] buf = new byte[1024];
+                    while ((len = is.read(buf)) != -1) {
+                        fos.write(buf, 0, len);
+                    }
+                    // 关流顺序,先打开的后关闭
+                    fos.close();
+                    is.close();
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("unzip error from ZipUtils", e);
+        } finally {
+            if(zipFile != null){
+                try {
+                    zipFile.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * 7z文件解压
+     * @param srcFile
+     */
+    public static void un7zFile(File srcFile,String destDirPath) {
+        //开始解压
+        SevenZFile zIn = null;
+        try {
+            zIn = new SevenZFile(srcFile);
+            SevenZArchiveEntry entry = null;
+            File file = null;
+            while ((entry = zIn.getNextEntry()) != null) {
+                if (!entry.isDirectory()) {
+                    file = new File(destDirPath, entry.getName());
+                    if (!file.exists()) {
+                        new File(file.getParent()).mkdirs();//创建此文件的上级目录
+                    }
+                    OutputStream out = new FileOutputStream(file);
+                    BufferedOutputStream bos = new BufferedOutputStream(out);
+                    int len = -1;
+                    byte[] buf = new byte[1024];
+                    while ((len = zIn.read(buf)) != -1) {
+                        bos.write(buf, 0, len);
+                    }
+                    // 关流顺序,先打开的后关闭
+                    bos.close();
+                    out.close();
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if(zIn != null){
+                try {
+                    zIn.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * rar文件解压
+     * @param rarFile
+     * @param destDirPath
+     * @throws Exception
+     */
+    public static void unRarFile(File rarFile, String destDirPath) {
+        File destDir=new File(destDirPath);
+        Archive archive = null;
+        FileOutputStream fos = null;
+        System.out.println("Starting 开始解压...");
+        try {
+            archive = new Archive(rarFile);
+            FileHeader fh = archive.nextFileHeader();
+            int count = 0;
+            File destFileName = null;
+            while (fh != null) {
+                System.out.println((++count) + ") " + fh.getFileNameString());
+                String compressFileName = fh.getFileNameString().trim();
+                destFileName = new File(destDir.getAbsolutePath() + "/" + compressFileName);
+                if (fh.isDirectory()) {
+                    if (!destFileName.exists()) {
+                        destFileName.mkdirs();
+                    }
+                    fh = archive.nextFileHeader();
+                    continue;
+                }
+                if (!destFileName.getParentFile().exists()) {
+                    destFileName.getParentFile().mkdirs();
+                }
+                fos = new FileOutputStream(destFileName);
+                archive.extractFile(fh, fos);
+                fos.close();
+                fos = null;
+                fh = archive.nextFileHeader();
+            }
+            archive.close();
+            archive = null;
+            System.out.println("Finished 解压完成!");
+        } catch (Exception e) {
+            e.printStackTrace();;
+        } finally {
+            if (fos != null) {
+                try {
+                    fos.close();
+                    fos = null;
+                } catch (Exception e) {
+                }
+            }
+            if (archive != null) {
+                try {
+                    archive.close();
+                    archive = null;
+                } catch (Exception e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * 采用命令行方式解压文件
+     * @param zipFile 压缩文件
+     * @param destDir 解压结果路径
+     * @param cmdPath WinRAR.exe的路径,也可以在代码中写死
+     * @return
+     */
+    public static boolean realExtract(File zipFile, String destDir,String cmdPath) {
+        // 解决路径中存在/..格式的路径问题
+        destDir = new File(destDir).getAbsoluteFile().getAbsolutePath();
+        while(destDir.contains("..")) {
+            String[] sepList = destDir.split("\\\\");
+            destDir = "";
+            for (int i = 0; i < sepList.length; i++) {
+                if(!"..".equals(sepList[i]) && i < sepList.length -1 && "..".equals(sepList[i+1])) {
+                    i++;
+                } else {
+                    destDir += sepList[i] + File.separator;
+                }
+            }
+        }
+
+        boolean bool = false;
+        if (!zipFile.exists()) {
+            return false;
+        }
+
+        // 开始调用命令行解压,参数-o+是表示覆盖的意思
+        String cmd = cmdPath + " X -o+ " + zipFile + " " + destDir;
+        System.out.println(cmd);
+        try {
+            Process proc = Runtime.getRuntime().exec(cmd);
+            if (proc.waitFor() != 0) {
+                if (proc.exitValue() == 0) {
+                    bool = false;
+                }
+            } else {
+                bool = true;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        System.out.println("解压" + (bool ? "成功" : "失败"));
+        return bool;
+    }
+
+}

+ 233 - 0
src/main/java/com/jeeplus/modules/ruralprojectrecords/utils/ImportExcelUtil.java

@@ -0,0 +1,233 @@
+package com.jeeplus.modules.ruralprojectrecords.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.google.common.collect.Lists;
+import com.jeeplus.common.utils.StringUtils;
+import org.apache.log4j.Logger;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author: 大猫
+ * @create: 2021-01-18 13:54
+ **/
+public class ImportExcelUtil {
+
+    private static Logger log = Logger.getLogger(ImportExcelUtil.class);
+
+    private final static String excel2003L = ".xls"; // 2003- 版本的excel
+    private final static String excel2007U = ".xlsx"; // 2007+ 版本的excel
+
+    private static Map<String,String> map = new LinkedHashMap();
+
+    /**
+     * 将流中的Excel数据转成List<Map>
+     *
+     * @param in
+     *            输入流
+     * @param fileName
+     *            文件名(判断Excel版本)
+     * @param mapping
+     *            字段名称映射
+     * @param sheetIndex
+     *            工作表编号
+     * @return
+     * @throws Exception
+     */
+    public static List<Map<String, Object>> parseExcel(InputStream in, String fileName,
+                                                       Map<String, String> mapping,Integer sheetIndex) throws Exception {
+        // 根据文件名来创建Excel工作薄
+        Workbook work = getWorkbook(in, fileName);
+        if (null == work) {
+            throw new Exception("创建Excel工作薄为空!");
+        }
+        Sheet sheet = null;
+        Row row = null;
+        Cell cell = null;
+        // 返回数据
+        List<Map<String, Object>> ls = Lists.newArrayList();
+
+        // 遍历Excel中的sheet
+        sheet = work.getSheet("审定信息");
+
+        if(null == sheet){
+            return null;
+        }
+
+        // 取第二行标题
+        row = sheet.getRow(1);
+        String title[] = null;
+        if (row != null) {
+            title = new String[row.getLastCellNum()];
+
+            for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
+                cell = row.getCell(y);
+                title[y] = (String) getCellValue(cell);
+                map.put((String)getCellValue(cell),"");
+            }
+
+        }
+        log.info(JSON.toJSONString(title));
+
+        // 遍历当前sheet中的所有行
+        for (int j = 2; j < sheet.getLastRowNum() + 1; j++) {
+            row = sheet.getRow(j);
+            Map<String, Object> m = new HashMap<String, Object>();
+            // 遍历所有的列
+            for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
+                cell = row.getCell(y);
+                if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK){
+                    String key = title[y];
+                    if(StringUtils.isNotBlank(mapping.get(key))){
+                        if(null == cell){
+                            m.put(mapping.get(key), "");
+                        }else{
+                            m.put(mapping.get(key), getCellValue(cell));
+                        }
+                    }
+                }
+            }
+            ls.add(m);
+        }
+        Iterator<Map<String,Object>> it = ls.iterator();
+        while(it.hasNext()){
+            Map<String,Object> x = it.next();
+            if(x.size() == 0){
+                it.remove();
+            }
+        }
+        return ls;
+    }
+
+    /**
+     * 描述:根据文件后缀,自适应上传文件的版本
+     *
+     * @param inStr
+     *            ,fileName
+     * @return
+     * @throws Exception
+     */
+    public static Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
+        Workbook wb = null;
+        String fileType = fileName.substring(fileName.lastIndexOf("."));
+        if (excel2003L.equals(fileType)) {
+            wb = new HSSFWorkbook(inStr); // 2003-
+        } else if (excel2007U.equals(fileType)) {
+            wb = new XSSFWorkbook(inStr); // 2007+
+        } else {
+            throw new Exception("解析的文件格式有误!");
+        }
+        return wb;
+    }
+
+    /**
+     * 描述:对表格中数值进行格式化
+     *
+     * @param cell
+     * @return
+     */
+    public static Object getCellValue(Cell cell) {
+        Object value = null;
+        DecimalFormat df = new DecimalFormat("0"); // 格式化number String字符
+        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd"); // 日期格式化
+        DecimalFormat df2 = new DecimalFormat("0"); // 格式化数字
+
+        switch (cell.getCellType()) {
+            case Cell.CELL_TYPE_STRING:
+                value = cell.getRichStringCellValue().getString();
+                break;
+            case Cell.CELL_TYPE_NUMERIC:
+                if ("General".equals(cell.getCellStyle().getDataFormatString())) {
+                    value = df.format(cell.getNumericCellValue());
+                } else if ("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) {
+                    value = sdf.format(cell.getDateCellValue());
+                } else {
+                    value = df2.format(cell.getNumericCellValue());
+                }
+                break;
+            case Cell.CELL_TYPE_BOOLEAN:
+                value = cell.getBooleanCellValue();
+                break;
+            case Cell.CELL_TYPE_BLANK:
+                value = "";
+                break;
+            default:
+                break;
+        }
+        return value;
+    }
+
+    public static void main(String[] args) throws Exception {
+        File file = new File("D:\\studn.xls");
+        FileInputStream fis = new FileInputStream(file);
+        Map<String, String> m = new HashMap<String, String>();
+        m.put("id", "id");
+        m.put("姓名", "name");
+        m.put("年龄", "age");
+        List<Map<String, Object>> ls = parseExcel(fis, file.getName(), m,0);
+        System.out.println(JSON.toJSONString(ls));
+    }
+
+    public static Map<String,String> mapInfo() {
+        Map map = new LinkedHashMap();
+        map.put("项目定义号","projectId");
+        map.put("项目名称","projectName");
+        map.put("单体工程wbs编号","wbsNum");
+        map.put("工程编号","programmeId");
+        map.put("工程名称","programmeName");
+        map.put("审计项目类型","auditItemsType");
+        map.put("电压等级","voltageLevel");
+        map.put("现场联系人","onSiteContact");
+        map.put("联系电话","contactNumber");
+        map.put("实际开工时间","actualStartTime");
+        map.put("实际竣工时间","actualEndTime");
+        map.put("施工单位名称","constructionUnit");
+        map.put("合同编号","contractId");
+        map.put("合同金额","contractSum");
+        map.put("计划开工时间","planStartTime");
+        map.put("计划竣工时间","planEndTime");
+        map.put("结算折扣率","settleDiscountRate");
+        map.put("土建结算送审金额(元)下浮后金额","civilSubmitSum");
+        map.put("安装结算送审金额(元)下浮后金额","installSubmitSum");
+        map.put("施工费送审金额小计(元)下浮后金额","buildSubmitSum");
+        map.put("甲供材送审金额(元)结算书中的物资金额","materialSubmitSum");
+        map.put("土建结算审定金额(元)下浮后金额","civilAuthorizeSum");
+        map.put("安装结算审定金额(元)下浮后金额","installAuthorizeSum");
+        map.put("施工费审定金额小计(元)下浮后金额","buildAuthorizeSum");
+        map.put("甲供材审定金额(元)","materialAuthorizeSum");
+        map.put("施工费核减金额(元)","buildDiscountSum");
+        map.put("施工费核减率(%)","buildDiscountRate");
+        map.put("施工单位诚信扣款(元)","creditDeduction");
+        map.put("建议结算款(元)","suggestedSettlement");
+        map.put("是否查看现场(必填),填是或者否","hasViewScene");
+        map.put("审计费(元)","auditFee");
+        map.put("审计部下发意见文号","optionNum");
+        map.put("事务所审计报告号(必填)","officeReportNo");
+        map.put("事务所名称","officeName");
+        map.put("事务所审计人员","officeAuditor");
+        map.put("打包时间","packTime");
+        map.put("审计应结束时间","planAuditTime");
+        map.put("审计方式","auditType");
+        map.put("备注","remarks");
+        map.put("审计专职","auditProfessional");
+        map.put("提交送审日期","submitApprovalTime");
+        map.put("送审人","submitApprovalMan");
+        map.put("送审部门","submitApprovalDepartment");
+        map.put("二级单位","secondaryUnit");
+        map.put("一级单位","firstLevelUnit");
+        map.put("送审单ID(勿动)","submissionFormId");
+        return map;
+    }
+
+}

+ 201 - 0
src/main/java/com/jeeplus/modules/ruralprojectrecords/web/SubProjectInfoController.java

@@ -0,0 +1,201 @@
+package com.jeeplus.modules.ruralprojectrecords.web;
+
+import com.jeeplus.common.bos.BOSClientUtil;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.MyBeanUtils;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.common.web.BaseController;
+import com.jeeplus.modules.ruralprojectrecords.entity.SubProjectInfo;
+import com.jeeplus.modules.ruralprojectrecords.service.SubProjectInfoService;
+import com.jeeplus.modules.sys.entity.User;
+import com.jeeplus.modules.sys.utils.UserUtils;
+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.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * 子项目controller
+ * @author: 徐滕
+ * @create: 2021-01-14 10:29
+ **/
+@Controller
+@RequestMapping(value = "${adminPath}/subProject/subProject")
+public class SubProjectInfoController extends BaseController {
+
+    @Autowired
+    private SubProjectInfoService subProjectInfoService;
+
+    @ModelAttribute
+    public SubProjectInfo get(@RequestParam(required=false) String id) {
+        SubProjectInfo entity = null;
+        if (StringUtils.isNotBlank(id)){
+            entity = subProjectInfoService.get(id);
+        }
+        if (entity == null){
+            entity = new SubProjectInfo();
+        }
+        return entity;
+    }
+
+    /**
+     * 子项目列表页面
+     * @param subProjectInfo
+     * @param request
+     * @param response
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = {"list", ""})
+    public String list(SubProjectInfo subProjectInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
+        //获取子项目信息
+        Page<SubProjectInfo> page = subProjectInfoService.findPage(new Page<SubProjectInfo>(request, response), subProjectInfo);
+        model.addAttribute("page", page);
+        model.addAttribute("parentProId", subProjectInfo.getParentProId());
+        return "modules/ruralprojectrecords/subProjectInfo/subProjectInfoList";
+    }
+
+    /**
+     * 增加,编辑子项目表单页面
+     */
+    @RequestMapping(value = "form")
+    public String form(SubProjectInfo subProjectInfo, Model model) {
+        if (subProjectInfo!=null&&StringUtils.isNotBlank(subProjectInfo.getId())) {
+            subProjectInfo = subProjectInfoService.get(subProjectInfo.getId());
+            //获取附件信息
+            subProjectInfoService.getWorkattachmentList(subProjectInfo);
+        }else {
+            subProjectInfo.setCreateBy(UserUtils.getUser());
+            subProjectInfo.setCreateDate(new Date());
+        }
+        model.addAttribute("subProjectInfo", subProjectInfo);
+        return "modules/ruralprojectrecords/subProjectInfo/subProjectInfoForm";
+    }
+
+    /**
+     * 查询项目定义号是否已存在
+     * @param subProjectInfo
+     * @return
+     */
+    @RequestMapping(value = "decideRepeat")
+    @ResponseBody
+    public Map decideRepeat(SubProjectInfo subProjectInfo){
+        Map<String,Object> map = new HashMap<>();
+        SubProjectInfo info = subProjectInfoService.decideRepeat(subProjectInfo);
+        if(null == info){
+            map.put("success",true);
+        }else{
+            map.put("success",false);
+            map.put("str","该项目定义号已存在!");
+        }
+        return map;
+    }
+
+    /**
+     * 保存、修改子项目
+     */
+    @RequestMapping(value = "save")
+    @ResponseBody
+    public Object save(SubProjectInfo subProjectInfo, Model model) {
+        Map<String,Object> map = new HashMap<>();
+        if (!beanValidator(model, subProjectInfo)){
+            return form(subProjectInfo, model);
+        }
+        try {
+            if (!subProjectInfo.getIsNewRecord()) {//编辑表单保存
+                SubProjectInfo t = subProjectInfoService.get(subProjectInfo.getId());//从数据库取出记录的值
+                    MyBeanUtils.copyBeanNotNull2Bean(subProjectInfo, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+                subProjectInfoService.save(t);//保存
+
+            } else {//新增表单保存
+                subProjectInfoService.save(subProjectInfo);//保存
+            }
+            map.put("str","保存成功!");
+        }catch (Exception e){
+            logger.error("保存子项目异常:",e);
+            map.put("str","保存子项目信息失败");
+        }
+        return map;
+    }
+
+    /**
+     * 查看子项目表单页面
+     * @param subProjectInfo
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = "view")
+    public String view(SubProjectInfo subProjectInfo, Model model) {
+        subProjectInfoService.getWorkattachmentList(subProjectInfo);
+        model.addAttribute("subProjectInfo", subProjectInfo);
+        return "modules/ruralprojectrecords/subProjectInfo/subProjectInfoView";
+    }
+
+
+    /**
+     * 查看子项目表单页面
+     * @param subProjectInfo
+     * @return
+     */
+    @RequestMapping(value = "delete")
+    @ResponseBody
+    public Object delete(SubProjectInfo subProjectInfo) {
+        Map<String,Object> map = new HashMap<>();
+        try {
+            //删除子项目信息
+            subProjectInfoService.delete(subProjectInfo);
+            map.put("str","删除子项目信息成功!");
+            map.put("success",true);
+        }catch (Exception e){
+            logger.error("删除子项目异常:",e);
+            map.put("str","删除子项目信息失败");
+            map.put("success",false);
+        }
+        return map;
+    }
+
+    /**
+     * 跳转上传压缩文件页
+     * @param subProjectInfo
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = "importFile")
+    public String importFile(SubProjectInfo subProjectInfo, Model model) {
+        model.addAttribute("subProjectInfo", subProjectInfo);
+        model.addAttribute("Global", new Global());
+        return "modules/ruralprojectrecords/subProjectInfo/subProjectFileForm";
+    }
+
+    /**
+     * 对压缩文件进行处理
+     * @param subProjectInfo
+     * @param file
+     * @return
+     * @throws IllegalStateException
+     * @throws IOException
+     */
+    @RequestMapping(value = "importCompressFile")
+    @ResponseBody
+    public Integer importCompressFile(SubProjectInfo subProjectInfo, MultipartFile file) throws IllegalStateException, IOException {
+        Integer result = subProjectInfoService.compressFileManage(subProjectInfo, file);
+        return result;
+    }
+
+}

+ 7 - 0
src/main/java/com/jeeplus/modules/sys/dao/WorkattachmentDao.java

@@ -48,4 +48,11 @@ public interface WorkattachmentDao extends CrudDao<Workattachment> {
     int updateAttachmentId(@Param("oldAttachmentId") String oldAttachmentId, @Param("newAttachmentId") String newAttachmentId);
 
     Integer deleteByDivIdType(String divIdType);
+
+    /**
+     * 根据attachmentId删除数据
+     * @param attachmentId
+     * @return
+     */
+    Integer deleteByAttachmentId(String attachmentId);
 }

+ 347 - 0
src/main/resources/mappings/modules/ruralprojectrecords/SubProjectInfoDao.xml

@@ -0,0 +1,347 @@
+<?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.ruralprojectrecords.dao.SubProjectInfoDao">
+
+	<sql id="subProjectInfoColumns">
+		distinct a.id AS "id",
+		a.create_by AS "createBy.id",
+		su.name AS "createBy.name",
+		a.create_date AS "createDate",
+		a.update_by AS "updateBy.id",
+		a.update_date AS "updateDate",
+		a.del_flag AS "delFlag",
+		a.project_id as "projectId",
+		a.parent_pro_id as "parentProId",
+		a.project_name as "projectName",
+		a.wbs_num as "wbsNum",
+		a.programme_id as "programmeId",
+		a.programme_name as "programmeName",
+		a.audit_items_type as "auditItemsType",
+		a.voltage_level as "voltageLevel",
+		a.on_site_contact as "onSiteContact",
+		a.contact_number as "contactNumber",
+		a.actual_start_time as "actualStartTime",
+		a.actual_end_time as "actualEndTime",
+		a.construction_unit as "constructionUnit",
+		a.contract_id as "contractId",
+		a.contract_sum as "contractSum",
+		a.plan_start_time as "planStartTime",
+		a.plan_end_time as "planEndTime",
+		a.settle_discount_rate as "settleDiscountRate",
+		a.civil_submit_sum as "civilSubmitSum",
+		a.install_submit_sum as "installSubmitSum",
+		a.build_submit_sum as "buildSubmitSum",
+		a.material_submit_sum as "materialSubmitSum",
+		a.civil_authorize_sum as "civilAuthorizeSum",
+		a.install_authorize_sum as "installAuthorizeSum",
+		a.build_authorize_sum as "buildAuthorizeSum",
+		a.material_authorize_sum as "materialAuthorizeSum",
+		a.build_discount_sum as "buildDiscountSum",
+		a.build_discount_rate as "buildDiscountRate",
+		a.credit_deduction as "creditDeduction",
+		a.suggested_settlement as "suggestedSettlement",
+		a.has_view_scene as "hasViewScene",
+		a.audit_fee as "auditFee",
+		a.option_num as "optionNum",
+		a.office_report_no as "officeReportNo",
+		a.office_name as "officeName",
+		a.office_auditor as "officeAuditor",
+		a.pack_time as "packTime",
+		a.plan_audit_time as "planAuditTime",
+		a.audit_type as "auditType",
+		a.remarks as "remarks",
+		a.audit_professional as "auditProfessional",
+		a.submit_approval_time as "submitApprovalTime",
+		a.submit_approval_man as "submitApprovalMan",
+		a.submit_approval_department as "submitApprovalDepartment",
+		a.secondary_unit as "secondaryUnit",
+		a.first_level_unit as "firstLevelUnit",
+		a.submission_form_id as "submissionFormId"
+	</sql>
+	
+	<sql id="projectRecordsJoins">
+		LEFT JOIN sys_user su ON su.id = a.create_by
+	</sql>
+	
+    
+	<select id="get" resultType="com.jeeplus.modules.ruralprojectrecords.entity.SubProjectInfo" >
+		SELECT
+			<include refid="subProjectInfoColumns"/>
+        FROM sub_project_info a
+		<include refid="projectRecordsJoins"/>
+		WHERE a.id = #{id}
+	</select>
+	
+	<select id="findList" resultType="com.jeeplus.modules.ruralprojectrecords.entity.SubProjectInfo" >
+		SELECT
+			<include refid="subProjectInfoColumns"/>
+		FROM sub_project_info a
+		<include refid="projectRecordsJoins"/>
+		<where>
+			a.del_flag = #{DEL_FLAG_NORMAL}
+			<!--项目定义号-->
+			<if test="projectId != null and projectId != ''">
+				AND a.project_id like concat('%',#{projectId},'%')
+			</if>
+			<!--项目名称-->
+			<if test="projectName != null and projectName != ''">
+				AND a.project_name like concat(concat('%',#{projectName}),'%')
+			</if>
+			<!--工程编号-->
+			<if test="programmeId != null and programmeId != ''">
+				AND a.programme_id like concat(concat('%',#{programmeId}),'%')
+			</if>
+			<!--工程名称-->
+			<if test="programmeName != null and programmeName != ''">
+				AND a.programme_name like concat(concat('%',#{programmeName}),'%')
+			</if>
+			<!--打包时间-->
+            <if test="beginDate !=null">
+                AND a.pack_time >= #{beginDate}
+            </if>
+            <if test="endDate !=null">
+                AND a.pack_time &lt;= #{endDate}
+            </if>
+			${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>
+
+    <select id="queryCount" resultType="int" >
+        SELECT count(DISTINCT a.id)
+        FROM sub_project_info a
+		<where>
+			a.del_flag = #{DEL_FLAG_NORMAL}
+			<!--项目定义号-->
+			<if test="projectId != null and projectId != ''">
+				AND a.project_id like concat('%',#{projectId},'%')
+			</if>
+			<!--项目名称-->
+			<if test="projectName != null and projectName != ''">
+				AND a.project_name like concat(concat('%',#{projectName}),'%')
+			</if>
+			<!--工程编号-->
+			<if test="programmeId != null and programmeId != ''">
+				AND a.programme_id like concat(concat('%',#{programmeId}),'%')
+			</if>
+			<!--工程名称-->
+			<if test="programmeName != null and programmeName != ''">
+				AND a.programme_name like concat(concat('%',#{programmeName}),'%')
+			</if>
+			<!--打包时间-->
+			<if test="beginDate !=null">
+				AND a.pack_time >= #{beginDate}
+			</if>
+			<if test="endDate !=null">
+				AND a.pack_time &lt;= #{endDate}
+			</if>
+			${sqlMap.dsf}
+		</where>
+    </select>
+
+	<select id="decideRepeat" resultType="com.jeeplus.modules.ruralprojectrecords.entity.SubProjectInfo" >
+		SELECT
+		<include refid="subProjectInfoColumns"/>
+		FROM sub_project_info a
+		<include refid="projectRecordsJoins"/>
+		<where>
+			a.project_id = #{projectId}
+			and a.del_flag = #{DEL_FLAG_NORMAL}
+			<if test="id!=null and id!=''">
+				and a.id != #{id}
+			</if>
+		</where>
+	</select>
+	
+	<insert id="insert">
+		insert into sub_project_info (
+		  id,
+		  create_by,
+		  create_date,
+		  update_by,
+		  update_date,
+		  del_flag,
+		  project_id,
+		  parent_pro_id,
+		  project_name,
+		  wbs_num,
+		  programme_id,
+		  programme_name,
+		  audit_items_type,
+		  voltage_level,
+		  on_site_contact,
+		  contact_number,
+		  actual_start_time,
+		  actual_end_time,
+		  construction_unit,
+		  contract_id,
+		  contract_sum,
+		  plan_start_time,
+		  plan_end_time,
+		  settle_discount_rate,
+		  civil_submit_sum,
+		  install_submit_sum,
+		  build_submit_sum,
+		  material_submit_sum,
+		  civil_authorize_sum,
+		  install_authorize_sum,
+		  build_authorize_sum,
+		  material_authorize_sum,
+		  build_discount_sum,
+		  build_discount_rate,
+		  credit_deduction,
+		  suggested_settlement,
+		  has_view_scene,
+		  audit_fee,
+		  option_num,
+		  office_report_no,
+		  office_name,
+		  office_auditor,
+		  pack_time,
+		  plan_audit_time,
+		  audit_type,
+		  remarks,
+		  audit_professional,
+		  submit_approval_time,
+		  submit_approval_man,
+		  submit_approval_department,
+		  secondary_unit,
+		  first_level_unit,
+		  submission_form_id,
+		  office_id,
+		  company_id
+		)
+		values
+		  (
+		    #{id},
+			#{createBy.id},
+			#{createDate},
+			#{updateBy.id},
+			#{updateDate},
+			#{delFlag},
+			#{projectId},
+			#{parentProId},
+			#{projectName},
+			#{wbsNum},
+			#{programmeId},
+			#{programmeName},
+			#{auditItemsType},
+			#{voltageLevel},
+			#{onSiteContact},
+			#{contactNumber},
+			#{actualStartTime},
+			#{actualEndTime},
+			#{constructionUnit},
+			#{contractId},
+			#{contractSum},
+			#{planStartTime},
+			#{planEndTime},
+			#{settleDiscountRate},
+			#{civilSubmitSum},
+			#{installSubmitSum},
+			#{buildSubmitSum},
+			#{materialSubmitSum},
+			#{civilAuthorizeSum},
+			#{installAuthorizeSum},
+			#{buildAuthorizeSum},
+			#{materialAuthorizeSum},
+			#{buildDiscountSum},
+			#{buildDiscountRate},
+			#{creditDeduction},
+			#{suggestedSettlement},
+			#{hasViewScene},
+			#{auditFee},
+			#{optionNum},
+			#{officeReportNo},
+			#{officeName},
+			#{officeAuditor},
+			#{packTime},
+			#{planAuditTime},
+			#{auditType},
+			#{remarks},
+			#{auditProfessional},
+			#{submitApprovalTime},
+			#{submitApprovalMan},
+			#{submitApprovalDepartment},
+			#{secondaryUnit},
+			#{firstLevelUnit},
+			#{submissionFormId},
+			#{office.id},
+			#{company.id}
+		  )
+	</insert>
+	
+	<update id="update">
+		update
+		  sub_project_info
+		set
+		  update_by = #{updateBy.id},
+		  update_date = #{updateDate},
+		  project_id = #{projectId},
+		  parent_pro_id = #{parentProId},
+		  project_name = #{projectName},
+		  wbs_num = #{wbsNum},
+		  programme_id = #{programmeId},
+		  programme_name = #{programmeName},
+		  audit_items_type = #{auditItemsType},
+		  voltage_level = #{voltageLevel},
+		  on_site_contact = #{onSiteContact},
+		  contact_number = #{contactNumber},
+		  actual_start_time = #{actualStartTime},
+		  actual_end_time = #{actualEndTime},
+		  construction_unit = #{constructionUnit},
+		  contract_id = #{contractId},
+		  contract_sum = #{contractSum},
+		  plan_start_time = #{planStartTime},
+		  plan_end_time = #{planEndTime},
+		  settle_discount_rate = #{settleDiscountRate},
+		  civil_submit_sum = #{civilSubmitSum},
+		  install_submit_sum = #{installSubmitSum},
+		  build_submit_sum = #{buildSubmitSum},
+		  material_submit_sum = #{materialSubmitSum},
+		  civil_authorize_sum = #{civilAuthorizeSum},
+		  install_authorize_sum = #{installAuthorizeSum},
+		  build_authorize_sum = #{buildAuthorizeSum},
+		  material_authorize_sum = #{materialAuthorizeSum},
+		  build_discount_sum = #{buildDiscountSum},
+		  build_discount_rate = #{buildDiscountRate},
+		  credit_deduction = #{creditDeduction},
+		  suggested_settlement = #{suggestedSettlement},
+		  has_view_scene = #{hasViewScene},
+		  audit_fee = #{auditFee},
+		  option_num = #{optionNum},
+		  office_report_no = #{officeReportNo},
+		  office_name = #{officeName},
+		  office_auditor = #{officeAuditor},
+		  pack_time = #{packTime},
+		  plan_audit_time = #{planAuditTime},
+		  audit_type = #{auditType},
+		  remarks = #{remarks},
+		  audit_professional = #{auditProfessional},
+		  submit_approval_time = #{submitApprovalTime},
+		  submit_approval_man = #{submitApprovalMan},
+		  submit_approval_department = #{submitApprovalDepartment},
+		  secondary_unit = #{secondaryUnit},
+		  first_level_unit = #{firstLevelUnit},
+		  submission_form_id = #{submissionFormId}
+		where id = #{id}
+	</update>
+	
+	<!--逻辑删除-->
+	<update id="delete">
+		UPDATE sub_project_info SET
+			del_flag = #{DEL_FLAG_DELETE}
+		WHERE id = #{id}
+	</update>
+
+	<delete id="deleteByParentProId">
+		delete from sub_project_info where parent_pro_id = #{parentProId}
+	</delete>
+</mapper>

+ 5 - 0
src/main/resources/mappings/modules/sys/WorkattachmentDao.xml

@@ -328,5 +328,10 @@
 		DELETE FROM work_attachment
 		WHERE div_id_type = #{divIdType}
 	</delete>
+
+	<delete id="deleteByAttachmentId">
+		DELETE FROM work_attachment
+		WHERE attachment_id = #{attachmentId}
+	</delete>
 	
 </mapper>

+ 15 - 0
src/main/webapp/WEB-INF/tags/table/subProjectAddRow.tag

@@ -0,0 +1,15 @@
+<%@ tag language="java" pageEncoding="UTF-8"%>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<%@ attribute name="url" type="java.lang.String" required="true"%>
+<%@ attribute name="title" type="java.lang.String" required="true"%>
+<%@ attribute name="width" type="java.lang.String" required="false"%>
+<%@ attribute name="height" type="java.lang.String" required="false"%>
+<%@ attribute name="target" type="java.lang.String" required="false"%>
+<%@ attribute name="label" type="java.lang.String" required="false"%>
+<button class="nav-btn nav-btn-add" data-toggle="tooltip" data-placement="left" onclick="add()" title="添加"><i class="fa fa-plus"></i> ${label==null?'添加':label}</button>
+<%-- 使用方法: 1.将本tag写在查询的form之前;2.传入table的id和controller的url --%>
+<script type="text/javascript">
+	function add(){
+		openDialog('${title}'+"登记",encodeURI("${url}"),"${width==null?'95%':width}", "${height==null?'95%':height}","${target}","inputForm"," layui-border-box");
+	}
+</script>

binární
src/main/webapp/static/images/filePhoto.jpg


+ 6 - 0
src/main/webapp/webpage/modules/ruralprojectrecords/cost/ruralCostProjectRecordsView.jsp

@@ -72,6 +72,12 @@
 </head>
 <body>
 <div class="single-form">
+	<div class="list-form-tab contentShadow shadowLTR" id="tabDiv">
+		<ul class="list-tabs" >
+			<li class="active"><a href="${ctx}/ruralProject/ruralProjectRecords/view?id=${projectRecords.id}">项目详情</a></li>
+			<li><a href="${ctx}/subProject/subProject/list?parentProId=${projectRecords.id}&projectType=${projectRecords.projectType}">子项目列表</a></li>
+		</ul>
+	</div>
 	<div class="container view-form">
 		<form:form id="inputForm" modelAttribute="projectRecords" action="${ctx}/ruralProject/ruralProjectRecords/saveAudit" method="post" class="form-horizontal">
 			<div class="form-group layui-row first">

+ 6 - 0
src/main/webapp/webpage/modules/ruralprojectrecords/ruralProjectRecordsView.jsp

@@ -72,6 +72,12 @@
 </head>
 <body>
 <div class="single-form">
+	<div class="list-form-tab contentShadow shadowLTR" id="tabDiv">
+		<ul class="list-tabs" >
+			<li class="active"><a href="${ctx}/ruralProject/ruralProjectRecords/view?id=${projectRecords.id}">项目详情</a></li>
+			<li><a href="${ctx}/subProject/subProject/list?parentProId=${projectRecords.id}&projectType=${projectRecords.projectType}">子项目列表</a></li>
+		</ul>
+	</div>
 	<div class="container view-form">
 		<form:form id="inputForm" modelAttribute="projectRecords" action="${ctx}/ruralProject/ruralProjectRecords/saveAudit" method="post" class="form-horizontal">
 			<div class="form-group layui-row first">

+ 514 - 0
src/main/webapp/webpage/modules/ruralprojectrecords/subProjectInfo/subProjectFileForm.jsp

@@ -0,0 +1,514 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<html>
+<head>
+	<title>个人信息</title>
+	<meta name="decorator" content="default"/>
+	<link rel="stylesheet" type="text/css" href="${ctxStatic}/webuploader-0.1.5/webuploader.css">
+	<link rel="stylesheet" type="text/css" href="${ctxStatic}/webuploader-0.1.5/demo.css">
+	  <script type="text/javascript">
+    // 添加全局站点信息
+    var BASE_URL = '/webuploader';
+    </script>
+	<script type="text/javascript" src="${ctxStatic}/webuploader-0.1.5/webuploader.js"></script>
+	<!-- <script type="text/javascript" src="${ctxStatic}/webuploader-0.1.5/demo.js"></script> -->
+    <style>
+        #uploader .placeholder{
+            min-height: 100px;
+        }
+    </style>
+</head>
+<body class="hideScroll">
+      <div class="wrapper wrapper-content animated fadeIn">
+        <input type="hidden" id="parentProId" name="parentProId" value="${subProjectInfo.parentProId}">
+        <input type="hidden" id="msg" name="msg" value="${msg}">
+        <input type="hidden" id="result" name="result" value="${result}">
+        <%--<div class="row">--%>
+            <%--<div class="col-sm-12">--%>
+                <div class="ibox float-e-margins">
+                    <div class="ibox-content">
+                        <div class="page-container">
+                            <p>您可以尝试文件拖拽或者点击添加压缩文件按钮,来上传文件(仅可上传 zip、rar、7z文件).</p>
+                            <p style="color: red">如果项目定义号重复则将会进行替代原项目信息</p>
+                            <div id="uploader" class="wu-example">
+                                <div class="queueList">
+                                    <div id="dndArea" class="placeholder">
+                                        <div id="filePicker"></div>
+                                        <p>将文件拖到这里</p>
+                                    </div>
+                                </div>
+                                <div class="statusBar" style="display:none;">
+                                    <div class="progress">
+                                        <span class="text">0%</span>
+                                        <span class="percentage"></span>
+                                    </div>
+                                    <div class="info"></div>
+                                    <div class="btns">
+                                        <div id="filePicker2"></div>
+                                        <div class="uploadBtn">开始上传</div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            <%--</div>--%>
+        <%--</div>--%>
+
+    </div>
+    <script>
+    jQuery(function() {
+        var $ = jQuery,    // just in case. Make sure it's not an other libaray.
+
+            $wrap = $('#uploader'),
+
+            // 文件容器
+            $queue = $('<ul class="filelist"></ul>')
+                .appendTo( $wrap.find('.queueList') ),
+
+            // 状态栏,包括进度和控制按钮
+            $statusBar = $wrap.find('.statusBar'),
+
+            // 文件总体选择信息。
+            $info = $statusBar.find('.info'),
+
+            // 上传按钮
+            $upload = $wrap.find('.uploadBtn'),
+
+            // 没选择文件之前的内容。
+            $placeHolder = $wrap.find('.placeholder'),
+
+            // 总体进度条
+            $progress = $statusBar.find('.progress').hide(),
+
+            // 添加的文件数量
+            fileCount = 0,
+
+            // 添加的文件总大小
+            fileSize = 0,
+
+            // 优化retina, 在retina下这个值是2
+            ratio = window.devicePixelRatio || 1,
+
+            // 缩略图大小
+            thumbnailWidth = 110 * ratio,
+            thumbnailHeight = 110 * ratio,
+
+            // 可能有pedding, ready, uploading, confirm, done.
+            state = 'pedding',
+
+            // 所有文件的进度信息,key为file id
+            percentages = {},
+
+            supportTransition = (function(){
+                var s = document.createElement('p').style,
+                    r = 'transition' in s ||
+                          'WebkitTransition' in s ||
+                          'MozTransition' in s ||
+                          'msTransition' in s ||
+                          'OTransition' in s;
+                s = null;
+                return r;
+            })(),
+
+            // WebUploader实例
+            uploader;
+
+        if ( !WebUploader.Uploader.support() ) {
+            alert( 'Web Uploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器');
+            throw new Error( 'WebUploader does not support the browser you are using.' );
+        }
+
+        // 实例化
+        uploader = WebUploader.create({
+            pick: {
+                id: '#filePicker',
+                label: '点击选择文件'
+            },
+            dnd: '#uploader .queueList',
+            paste: document.body,
+
+            accept: {
+                title: '',
+                extensions: 'zip,rar,7z',
+                mimeTypes: 'zip,rar,7z'
+            },
+
+            // swf文件路径
+            swf: BASE_URL + '/js/Uploader.swf',
+
+            disableGlobalDnd: true,
+
+            chunked: true,
+            // server: 'http://webuploader.duapp.com/server/fileupload.php',
+            server: '${ctx}/subProject/subProject/importCompressFile?parentProId='+$("#parentProId").val(),
+            fileNumLimit: 1,//一次最多上传多少个文件
+        });
+
+        // 添加“添加文件”的按钮,
+//        uploader.addButton({
+//            id: '#filePicker2',
+//            label: '继续添加'
+//        });
+
+        uploader.on('error', function(handler) {
+            if (handler == "Q_EXCEED_NUM_LIMIT") {
+                parent.layer.msg("只能上传一个压缩文件",{icon:5});
+            }
+        });
+        uploader.on('uploadSuccess', function(file,response) {
+            console.log(response._raw);
+            var result = response._raw;
+            $("#result").val(result);
+
+        });
+        // 当有文件添加进来时执行,负责view的创建
+        function addFile( file ) {
+            var $li = $( '<li id="' + file.id + '">' +
+                    '<p class="title">' + file.name + '</p>' +
+                    '<p class="imgWrap"></p>'+
+                    '<p class="progress"><span></span></p>' +
+                    '</li>' ),
+
+                $btns = $('<div class="file-panel">' +
+                    '<span class="cancel">删除</span>' +
+                    '</div>').appendTo( $li ),
+                $prgress = $li.find('p.progress span'),
+                $wrap = $li.find( 'p.imgWrap' ),
+                $info = $('<p class="error"></p>'),
+
+                showError = function( code ) {
+                    switch( code ) {
+                        case 'exceed_size':
+                            text = '文件大小超出';
+                            break;
+
+                        case 'interrupt':
+                            text = '上传暂停';
+                            break;
+
+                        default:
+                            text = '上传失败,请重试';
+                            break;
+                    }
+
+                    $info.text( text ).appendTo( $li );
+                };
+
+            if ( file.getStatus() === 'invalid' ) {
+                showError( file.statusText );
+            } else {
+                // @todo lazyload
+                $wrap.text( '预览中' );
+                uploader.makeThumb( file, function( error, src ) {
+                    /*if ( error ) {
+                        $wrap.text( '不能预览' );
+                        return;
+                    }*/
+
+                    var img = $('<img src="${ctxStatic}/images/filePhoto.jpg">');
+                    $wrap.empty().append( img );
+                }, thumbnailWidth, thumbnailHeight );
+
+                percentages[ file.id ] = [ file.size, 0 ];
+                file.rotation = 0;
+            }
+
+            file.on('statuschange', function( cur, prev ) {
+                if ( prev === 'progress' ) {
+                    $prgress.hide().width(0);
+                } else if ( prev === 'queued' ) {
+                    $li.off( 'mouseenter mouseleave' );
+                    $btns.remove();
+                }
+
+                // 成功
+                if ( cur === 'error' || cur === 'invalid' ) {
+                    console.log( file.statusText );
+                    showError( file.statusText );
+                    percentages[ file.id ][ 1 ] = 1;
+                } else if ( cur === 'interrupt' ) {
+                    showError( 'interrupt' );
+                } else if ( cur === 'queued' ) {
+                    percentages[ file.id ][ 1 ] = 0;
+                } else if ( cur === 'progress' ) {
+                    $info.remove();
+                    $prgress.css('display', 'block');
+                } else if ( cur === 'complete' ) {
+                    $li.append( '<span class="success"></span>' );
+                }
+
+                $li.removeClass( 'state-' + prev ).addClass( 'state-' + cur );
+            });
+
+            $li.on( 'mouseenter', function() {
+                $btns.stop().animate({height: 30});
+            });
+
+            $li.on( 'mouseleave', function() {
+                $btns.stop().animate({height: 0});
+            });
+
+            $btns.on( 'click', 'span', function() {
+                var index = $(this).index(),
+                    deg;
+
+                switch ( index ) {
+                    case 0:
+                        uploader.removeFile( file );
+                        return;
+
+                    case 1:
+                        file.rotation += 90;
+                        break;
+
+                    case 2:
+                        file.rotation -= 90;
+                        break;
+                }
+
+                if ( supportTransition ) {
+                    deg = 'rotate(' + file.rotation + 'deg)';
+                    $wrap.css({
+                        '-webkit-transform': deg,
+                        '-mos-transform': deg,
+                        '-o-transform': deg,
+                        'transform': deg
+                    });
+                } else {
+                    $wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')');
+                    // use jquery animate to rotation
+                    // $({
+                    //     rotation: rotation
+                    // }).animate({
+                    //     rotation: file.rotation
+                    // }, {
+                    //     easing: 'linear',
+                    //     step: function( now ) {
+                    //         now = now * Math.PI / 180;
+
+                    //         var cos = Math.cos( now ),
+                    //             sin = Math.sin( now );
+
+                    //         $wrap.css( 'filter', "progid:DXImageTransform.Microsoft.Matrix(M11=" + cos + ",M12=" + (-sin) + ",M21=" + sin + ",M22=" + cos + ",SizingMethod='auto expand')");
+                    //     }
+                    // });
+                }
+
+
+            });
+
+            $li.appendTo( $queue );
+        }
+
+        // 负责view的销毁
+        function removeFile( file ) {
+            var $li = $('#'+file.id);
+
+            delete percentages[ file.id ];
+            updateTotalProgress();
+            $li.off().find('.file-panel').off().end().remove();
+        }
+
+        function updateTotalProgress() {
+            var loaded = 0,
+                total = 0,
+                spans = $progress.children(),
+                percent;
+
+            $.each( percentages, function( k, v ) {
+                total += v[ 0 ];
+                loaded += v[ 0 ] * v[ 1 ];
+            } );
+
+            percent = total ? loaded / total : 0;
+
+            spans.eq( 0 ).text( Math.round( percent * 100 ) + '%' );
+            spans.eq( 1 ).css( 'width', Math.round( percent * 100 ) + '%' );
+            updateStatus();
+        }
+        var count = 0;
+        function updateStatus() {
+            var text = '', stats;
+
+            if ( state === 'ready' ) {
+                text = '选中' + fileCount + '个文件,共' +
+                        WebUploader.formatSize( fileSize ) + '。';
+            } else if ( state === 'confirm' ) {
+                stats = uploader.getStats();
+                if ( stats.uploadFailNum ) {
+                    text = '已成功上传' + stats.successNum+ '个文件,'+
+                        stats.uploadFailNum + '个文件上传失败,<a class="retry" href="javascript:void(0)">重新上传</a>失败文件或<a class="ignore" href="javascript:void(0)">忽略</a>'
+                }
+
+            } else {
+                stats = uploader.getStats();
+                text = '上传文件成功!';
+
+                if ( stats.uploadFailNum ) {
+                    text ='上传文件失败!';
+                }
+            }
+            $info.html( text );
+        }
+
+        function setState( val ) {
+            var file, stats;
+
+            if ( val === state ) {
+                return;
+            }
+
+            $upload.removeClass( 'state-' + state );
+            $upload.addClass( 'state-' + val );
+            state = val;
+
+            switch ( state ) {
+                case 'pedding':
+                    $placeHolder.removeClass( 'element-invisible' );
+                    $queue.parent().removeClass('filled');
+                    $queue.hide();
+                    $statusBar.addClass( 'element-invisible' );
+                    uploader.refresh();
+                    break;
+
+                case 'ready':
+                    $placeHolder.addClass( 'element-invisible' );
+                    $( '#filePicker2' ).removeClass( 'element-invisible');
+                    $queue.parent().addClass('filled');
+                    $queue.show();
+                    $statusBar.removeClass('element-invisible');
+                    uploader.refresh();
+                    break;
+
+                case 'uploading':
+                    $( '#filePicker2' ).addClass( 'element-invisible' );
+                    $progress.show();
+                    $upload.text( '暂停上传' );
+                    break;
+
+                case 'paused':
+                    $progress.show();
+                    $upload.text( '继续上传' );
+                    break;
+
+                case 'confirm':
+                    $progress.hide();
+                    $upload.text( '开始上传' ).addClass( 'disabled' );
+
+                    var result = $("#result").val();
+                    var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
+                    if(undefined != result && null != result && "" != result && 0 ==result){
+                        top.layer.msg("上传成功数据 "+result+" 条,压缩包或损坏,请检查后重新上传!", {icon: 0});
+
+                        top.layer.close(index);
+                    }else if(undefined != result && null != result && "" != result && result>0){
+                        top.layer.msg("上传成功数据 "+result+" 条,上传成功!", {icon: 0});
+                        top.layer.close(index);
+                    }
+
+
+                    stats = uploader.getStats();
+                    if ( stats.successNum && !stats.uploadFailNum ) {
+                        setState( 'finish' );
+                        return;
+                    }
+                    break;
+                case 'finish':
+                    stats = uploader.getStats();
+                    if ( stats.successNum ) {
+                      //  alert( '上传成功' );
+                        
+                    } else {
+                        // 没有成功的文件,重设
+                        state = 'done';
+                        location.reload();
+                    }
+                    break;
+            }
+
+            updateStatus();
+        }
+
+        uploader.onUploadProgress = function( file, percentage ) {
+            var $li = $('#'+file.id),
+                $percent = $li.find('.progress span');
+
+            $percent.css( 'width', percentage * 100 + '%' );
+            percentages[ file.id ][ 1 ] = percentage;
+            updateTotalProgress();
+        };
+
+        uploader.onFileQueued = function( file ) {
+            fileCount++;
+            fileSize += file.size;
+
+            if ( fileCount === 1 ) {
+                $placeHolder.addClass( 'element-invisible' );
+                $statusBar.show();
+            }
+
+            addFile( file );
+            setState( 'ready' );
+            updateTotalProgress();
+        };
+
+        uploader.onFileDequeued = function( file ) {
+            fileCount--;
+            fileSize -= file.size;
+
+            if ( !fileCount ) {
+                setState( 'pedding' );
+            }
+
+            removeFile( file );
+            updateTotalProgress();
+
+        };
+
+        uploader.on( 'all', function( type ) {
+            var stats;
+            switch( type ) {
+                case 'uploadFinished':
+                    setState( 'confirm' );
+                    break;
+
+                case 'startUpload':
+                    setState( 'uploading' );
+                    break;
+
+                case 'stopUpload':
+                    setState( 'paused' );
+                    break;
+
+            }
+        });
+
+        $upload.on('click', function() {
+            if ( $(this).hasClass( 'disabled' ) ) {
+                return false;
+            }
+
+            if ( state === 'ready' ) {
+                uploader.upload();
+            } else if ( state === 'paused' ) {
+                uploader.upload();
+            } else if ( state === 'uploading' ) {
+                uploader.stop();
+            }
+        });
+
+        $info.on( 'click', '.retry', function() {
+            uploader.retry();
+        } );
+
+        $info.on( 'click', '.ignore', function() {
+            alert( 'todo' );
+        } );
+
+        $upload.addClass( 'state-' + state );
+        updateTotalProgress();
+    });
+    </script>
+</body>
+</html>

+ 782 - 0
src/main/webapp/webpage/modules/ruralprojectrecords/subProjectInfo/subProjectInfoForm.jsp

@@ -0,0 +1,782 @@
+<%@ 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" src="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.js"></script>
+    <script type="text/javascript" src="${ctxStatic}/iCheck/icheck.min.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
+    <style>
+        #projectDesc-error{
+            left:0;
+            top:82px;
+        }
+        .layui-layer-dialog{
+            background: red;
+        }
+        td input{
+            margin-left:-10px !important;
+            height: 42px !important;
+        }
+        .disables {
+            pointer-events: none;
+        }
+        .notDisables {
+            pointer-events: all;
+        }
+        .forbidden{
+             background-color:#c2c2c2;
+         }
+
+        .notForbidden{
+             background-color:#3ca2e0;
+         }
+    </style>
+    <script type="text/javascript">
+        var validateForm;
+        var isMasterClient = true;//是否是委托方
+        var clientCount = 0;
+        function doSubmit(i){//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if(validateForm.form()){
+                $("#inputForm").submit();
+                return true;
+            }else{
+                parent.layer.msg("信息未填写完整!", {icon: 5});
+            }
+
+            return false;
+        }
+        $(document).ready(function() {
+            var radioVal ;
+            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: '#actualStartTime', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+                , trigger: 'click'
+                , trigger: 'click'
+            });
+            laydate.render({
+                elem: '#actualEndTime', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+                , trigger: 'click'
+                , trigger: 'click'
+            });
+            laydate.render({
+                elem: '#planStartTime', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+                , trigger: 'click'
+                , trigger: 'click'
+            });
+            laydate.render({
+                elem: '#planEndTime', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+                , trigger: 'click'
+                , trigger: 'click'
+            });
+            laydate.render({
+                elem: '#packTime', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+                , trigger: 'click'
+                , trigger: 'click'
+            });
+            laydate.render({
+                elem: '#planAuditTime', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+                , trigger: 'click'
+                , trigger: 'click'
+            });
+            laydate.render({
+                elem: '#submitApprovalTime', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+                , trigger: 'click'
+                , trigger: 'click'
+            });
+
+
+            $("#attachment_btn").click(function () {
+                $("#attachment_file").click();
+            });;
+            $("#gistdata_btn").click(function () {
+                $("#gistdata_file").click();
+            });;
+            $("#other_btn").click(function () {
+                $("#other_file").click();
+            });
+        });
+
+        function insertTitle(tValue){
+            var files = $("#attachment_file")[0].files;
+            for(var i=0;i<files.length;i++) {
+                var file = files[i];
+                var attachmentId = "";
+                var attachmentFlag = "86";
+                console.log(file);
+                var timestamp = new Date().getTime();
+
+                var storeAs = "newxgccpm-test/attachment-file/basedData/" + timestamp + "/" + file['name'];
+                var uploadPath = "http://gangwan-app.oss-cn-hangzhou.aliyuncs.com/" + storeAs;
+                /*将这段字符串存到数据库即可*/
+                var divId = "_subAttachment";
+                $("#addFile" + divId).show();
+                multipartUploadWithSts(storeAs, file, attachmentId, attachmentFlag, uploadPath, divId, "0");
+            }
+        }
+
+        function gistdataInsertTitle(tValue){
+            var files = $("#gistdata_file")[0].files;
+            for(var i=0;i<files.length;i++) {
+                var file = files[i];
+                var gistdataId = "";
+                var gistdataFlag = "152";
+                console.log(file);
+                var timestamp = new Date().getTime();
+
+                var storeAs = "newxgccpm-test/attachment-file/basedData/" + timestamp + "/" + file['name'];
+                var uploadPath = "http://gangwan-app.oss-cn-hangzhou.aliyuncs.com/" + storeAs;
+                /*将这段字符串存到数据库即可*/
+                var divId = "_subGistdata";
+                $("#addFile" + divId).show();
+                multipartUploadWithSts(storeAs, file, gistdataId, gistdataFlag, uploadPath, divId, "0");
+            }
+        }
+
+        function otherInsertTitle(tValue){
+            var files = $("#other_file")[0].files;
+            for(var i=0;i<files.length;i++) {
+                var file = files[i];
+                var attachmentId = "";
+                var attachmentFlag = "153";
+                console.log(file);
+                var timestamp = new Date().getTime();
+
+                var storeAs = "newxgccpm-test/attachment-file/basedData/" + timestamp + "/" + file['name'];
+                var uploadPath = "http://gangwan-app.oss-cn-hangzhou.aliyuncs.com/" + storeAs;
+                /*将这段字符串存到数据库即可*/
+                var divId = "_subOther";
+                $("#addFile" + divId).show();
+                multipartUploadWithSts(storeAs, file, attachmentId, attachmentFlag, uploadPath, divId, "0");
+            }
+        }
+
+
+        function addFile() {
+            $("#attachment_file").click();
+        }
+
+        function addRow(list, idx, tpl, row){
+            // var idx1 = $("#workClientLinkmanList tr").length;
+            bornTemplete(list, idx, tpl, row, idx);
+        }
+
+        function bornTemplete(list, idx, tpl, row, idx1){
+            $(list).append(Mustache.render(tpl, {
+                idx: idx, delBtn: true, row: row,
+                order:idx1 + 1
+            }));
+            $(list+idx).find("select").each(function(){
+                $(this).val($(this).attr("data-value"));
+            });
+            $(list+idx).find("input[type='checkbox'], input[type='radio']").each(function(){
+                var ss = $(this).attr("data-value").split(',');
+                for (var i=0; i<ss.length; i++){
+                    if($(this).val() == ss[i]){
+                        $(this).attr("checked","checked");
+                    }
+                }
+            });
+        }
+
+        function delRow(obj, prefix){
+            var id = $(prefix+"_id");
+            var delFlag = $(prefix+"_delFlag");
+            $(obj).parent().parent().remove();
+        }
+
+        function decideRepeat() {
+            var projectId = $("#projectId").val();
+            var id = $("#id").val();
+            $.ajax({
+                type:"post",
+                url: "${ctx}/subProject/subProject/decideRepeat?projectId="+projectId +"&id=" + id,
+                dataType:"json",
+                success:function(data){
+                    if(data.success) {
+                    }else {
+                        top.layer.msg(data.str, {icon: 0});
+                        $("#projectId").val("")
+                    }
+                }
+            })
+        }
+    </script>
+</head>
+<body>
+<div class="single-form">
+    <div class="container">
+        <sys:message content="${message}"/>
+        <form:form id="inputForm" modelAttribute="subProjectInfo" action="${ctx}/subProject/subProject/save" method="post" class="form-horizontal">
+            <form:hidden path="id"/>
+            <form:hidden path="parentProId"/>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>项目基本信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label"><span class="require-item">*</span>项目定义号:</label>
+                    <div class="layui-input-block">
+                        <form:input path="projectId" htmlEscape="false"  class="form-control layui-input required" onchange="decideRepeat()"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label"><span class="require-item">*</span>项目名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="projectName" htmlEscape="false"  class="form-control layui-input required"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">单体工程WBS编号:</label>
+                    <div class="layui-input-block">
+                        <form:input path="wbsNum" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">工程编号:</label>
+                    <div class="layui-input-block">
+                        <form:input path="programmeId" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">工程名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="programmeName" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">审计项目类型:</label>
+                    <div class="layui-input-block">
+                        <form:input path="auditItemsType" htmlEscape="false"  class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">创建人:</label>
+                    <div class="layui-input-block">
+                        <form:input path="createBy.name" htmlEscape="false"  readonly="true"  class="form-control  layui-input"/>
+                        <form:hidden path="createBy.id" htmlEscape="false"   readonly="true"  class="form-control  layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">电压等级:</label>
+                    <div class="layui-input-block">
+                        <form:input path="voltageLevel" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">现场联系人:</label>
+                    <div class="layui-input-block">
+                        <form:input path="onSiteContact" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">联系电话:</label>
+                    <div class="layui-input-block">
+                        <form:input path="contactNumber" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">实际开工时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="actualStartTime" name="actualStartTime" value="<fmt:formatDate value="${subProjectInfo.actualStartTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">实际竣工时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="actualEndTime" name="actualEndTime" value="<fmt:formatDate value="${subProjectInfo.actualEndTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>合同信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工单位名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="constructionUnit" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">合同编号:</label>
+                    <div class="layui-input-block">
+                        <form:input path="contractId" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">合同金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="contractSum" htmlEscape="false" class="form-control layui-input number"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">计划开工时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="planStartTime" name="planStartTime" value="<fmt:formatDate value="${subProjectInfo.planStartTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">计划竣工时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="planEndTime" name="planEndTime" value="<fmt:formatDate value="${subProjectInfo.planEndTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">结算折扣率:</label>
+                    <div class="layui-input-block">
+                        <form:input path="settleDiscountRate" htmlEscape="false" class="form-control layui-input number"/>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>送审信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">土建结算送审金额(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="civilSubmitSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">安装结算送审金额(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="installSubmitSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工费送审金额小计(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="buildSubmitSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">甲供材送审金额(元)结算书中的物资金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="materialSubmitSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>审定信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">土建结算审定金额(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="civilAuthorizeSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">安装结算审定金额(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="installAuthorizeSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工费审定金额小计(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="buildAuthorizeSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">甲供材审定金额(元):</label>
+                    <div class="layui-input-block">
+                        <form:input path="materialAuthorizeSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工费核减金额(元):</label>
+                    <div class="layui-input-block">
+                        <form:input path="buildDiscountSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工费核减率(%):</label>
+                    <div class="layui-input-block">
+                        <form:input path="buildDiscountRate" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工单位诚信扣款(元):</label>
+                    <div class="layui-input-block">
+                        <form:input path="creditDeduction" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">建议结算款(元):</label>
+                    <div class="layui-input-block">
+                        <form:input path="suggestedSettlement" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">是否查看现场:</label>
+                    <div class="layui-input-block">
+                        <select id="hasViewScene" name="hasViewScene" class="form-control editable-select layui-input">
+                            <option value="">请选择</option>
+                            <option value="是" ${subProjectInfo.hasViewScene=='是'?'selected':''}>是</option>
+                            <option value="否" ${subProjectInfo.hasViewScene=='否'?'selected':''}>否</option>
+                        </select>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>审计费信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">审计费(元):</label>
+                    <div class="layui-input-block">
+                        <form:input path="auditFee" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>审计意见及报告信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">审计部下发意见文号:</label>
+                    <div class="layui-input-block">
+                        <form:input path="optionNum" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">事务所审计报告号(必填):</label>
+                    <div class="layui-input-block">
+                        <form:input path="officeReportNo" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>审计进度信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">事务所名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="officeName" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">事务所审计人员:</label>
+                    <div class="layui-input-block">
+                        <form:input path="officeAuditor" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">打包时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="packTime" name="packTime" value="<fmt:formatDate value="${subProjectInfo.packTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">审计应结束时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="planAuditTime" name="planAuditTime" value="<fmt:formatDate value="${subProjectInfo.planAuditTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">审计方式:</label>
+                    <div class="layui-input-block">
+                        <form:input path="auditType" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>备注</h2></div>
+                <div class="layui-item layui-col-sm12 lw7 with-textarea">
+                    <label class="layui-form-label">备注:</label>
+                    <div class="layui-input-block">
+                        <form:textarea path="remarks" htmlEscape="false" rows="4"  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 layui-col-sm6 lw7">
+                    <label class="layui-form-label">审计专职:</label>
+                    <div class="layui-input-block">
+                        <form:input path="auditProfessional" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">提交送审日期:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="submitApprovalTime" name="submitApprovalTime" value="<fmt:formatDate value="${subProjectInfo.submitApprovalTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">送审人:</label>
+                    <div class="layui-input-block">
+                        <form:input path="submitApprovalMan" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">送审部门:</label>
+                    <div class="layui-input-block">
+                        <form:input path="submitApprovalDepartment" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">二级单位:</label>
+                    <div class="layui-input-block">
+                        <form:input path="secondaryUnit" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">一级单位:</label>
+                    <div class="layui-input-block">
+                        <form:input path="firstLevelUnit" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">送审单ID(勿动):</label>
+                    <div class="layui-input-block">
+                        <form:input path="submissionFormId" htmlEscape="false" class="form-control layui-input"/>
+                    </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_subAttachment" style="display: none" class="upload-progress">
+                    <span id="fileName_subAttachment" ></span>
+                    <span id="_attachment" ></span>
+                    <b><span id="baifenbi_subAttachment" ></span></b>
+                    <div class="progress">
+                        <div id="jindutiao_subAttachment" 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_subAttachment">
+                        <c:forEach items="${subProjectInfo.workAttachments}" var = "workClientAttachment" varStatus="status">
+                            <c:if test="${workClientAttachment.divIdType eq '_subAttachment'}">
+                                <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:if>
+                        </c:forEach>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>依据性资料</h2></div>
+                <div class="layui-item nav-btns">
+                    <a id="gistdata_btn" class="nav-btn nav-btn-add" title="添加附件"><i class="fa fa-plus"></i>&nbsp;添加附件</a>
+                </div>
+                <div id="addFile_subGistdata" style="display: none" class="upload-progress">
+                    <span id="fileName_subGistdata" ></span>
+                    <span id="_gistdata" ></span>
+                    <b><span id="baifenbi_subGistdata" ></span></b>
+                    <div class="progress">
+                        <div id="jindutiao_subGistdata" class="progress-bar" style="width: 0%" aria-valuenow="0">
+                        </div>
+                    </div>
+                </div>
+                <input id="gistdata_file" type="file" name="gistdata_file" multiple="multiple" style="display: none;" onChange="if(this.value)gistdataInsertTitle(this.value);"/>
+                <span id="gistdata_title"></span>
+                <div class="layui-item layui-col-xs12" style="padding:0 16px;">
+                    <table id="gistdata_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_subGistdata">
+                        <c:forEach items="${subProjectInfo.workAttachments}" var = "workClientAttachment" varStatus="status">
+                            <c:if test="${workClientAttachment.divIdType eq '_subGistdata'}">
+                                <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','addFileGistdata')" class="op-btn op-btn-delete" ><i class="fa fa-trash"></i>&nbsp;删除</a>
+                                            </c:if>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:if>
+                        </c:forEach>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>其他文件</h2></div>
+                <div class="layui-item nav-btns">
+                    <a id="other_btn" class="nav-btn nav-btn-add" title="添加附件"><i class="fa fa-plus"></i>&nbsp;添加附件</a>
+                </div>
+                <div id="addFile_subOther" style="display: none" class="upload-progress">
+                    <span id="fileName_subOther" ></span>
+                    <span id="_other" ></span>
+                    <b><span id="baifenbi_subOther" ></span></b>
+                    <div class="progress">
+                        <div id="jindutiao_subOther" class="progress-bar" style="width: 0%" aria-valuenow="0">
+                        </div>
+                    </div>
+                </div>
+                <input id="other_file" type="file" name="other_file" multiple="multiple" style="display: none;" onChange="if(this.value)otherInsertTitle(this.value);"/>
+                <span id="other_title"></span>
+                <div class="layui-item layui-col-xs12" style="padding:0 16px;">
+                    <table id="upTable_other" 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_subOther">
+                        <c:forEach items="${subProjectInfo.workAttachments}" var = "workClientAttachment" varStatus="status">
+                            <c:if test="${workClientAttachment.divIdType eq '_subOther'}">
+                                <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','addFileOther')" class="op-btn op-btn-delete" ><i class="fa fa-trash"></i>&nbsp;删除</a>
+                                            </c:if>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:if>
+                        </c:forEach>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+            <div class="form-group layui-row page-end"></div>
+        </form:form>
+    </div>
+</div>
+</body>
+</html>

+ 384 - 0
src/main/webapp/webpage/modules/ruralprojectrecords/subProjectInfo/subProjectInfoList.jsp

@@ -0,0 +1,384 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp"%>
+<html>
+<head>
+	<title>子项目列表</title>
+	<meta name="decorator" content="default"/>
+	<%--<script src="${ctxStatic}/layer-v2.3/laydate/laydate.js"></script>--%>
+	<script type="text/javascript">
+        $(document).ready(function() {
+
+            //搜索框收放
+            $('#moresee').click(function(){
+                if($('#moresees').is(':visible'))
+                {
+                    $('#moresees').slideUp(0,resizeListWindow2);
+                    $('#moresee i').removeClass("glyphicon glyphicon-menu-up").addClass("glyphicon glyphicon-menu-down");
+                }else{
+                    $('#moresees').slideDown(0,resizeListWindow2);
+                    $('#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'
+				, trigger: 'click'
+            });
+            laydate.render({
+                elem: '#endDate', //目标元素。由于laydate.js封装了一个轻量级的选择器引擎,因此elem还允许你传入class、tag但必须按照这种方式 '#id .class'
+                event: 'focus', //响应事件。如果没有传入event,则按照默认的click
+                type : 'date'
+				, trigger: 'click'
+            });
+        });
+
+        function reset() {
+            $("#searchForm").resetForm();
+        }
+        function openDialog(title,url,width,height,target,formId,tableId) {
+
+            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,
+				skin:"two-btns",
+				maxmin: false, //开启最大化最小化按钮
+				content: url ,
+				btn: ['确定','关闭'],
+				yes: 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中展示
+					inputForm.attr("action","${ctx}/subProject/subProject/save");//表单提交成功后,从服务器返回的url在当前tab中展示
+					var $document = iframeWin.contentWindow.document;
+
+					formSubmit2($document,formId,index,tableId);
+
+				},
+				cancel: function(index){
+				}
+			});
+        }
+
+			function formSubmit2($document,inputForm,index,tableId){
+
+				var validateForm = $($document.getElementById(inputForm)).validate({
+					submitHandler: function(form){
+						loading('正在提交,请稍等...');
+						form.submit();
+					},
+					errorContainer: "#messageBox",
+					errorPlacement: function(error, element) {
+						$($document.getElementById("#messageBox")).text("输入有误,请先更正。");
+						if (element.is(":checkbox")||element.is(":radio")||element.parent().is(".input-append")){
+							error.appendTo(element.parent().parent());
+						} else {
+							error.insertAfter(element);
+						}
+					}
+				});
+				if(validateForm.form()){
+					$($document.getElementById(inputForm)).ajaxSubmit({
+						success:function(data) {
+							var d = data;
+							//输出提示信息
+							if(d.str.length>0){
+								parent.layer.msg(d.str,{icon:1});
+							}
+							window.location.reload();
+							//关闭当前页
+							top.layer.close(index)
+						}
+					});
+				}
+			}
+        function openDialogre(title,url,width,height,target,formId,tableId) {
+			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,
+				skin:"two-btns",
+				maxmin: false, //开启最大化最小化按钮
+				content: url ,
+				btn: ['确定','关闭'],
+				yes: 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中展示
+					inputForm.attr("action","${ctx}/subProject/subProject/save");//表单提交成功后,从服务器返回的url在当前tab中展示
+					var $document = iframeWin.contentWindow.document;
+
+					formSubmit2($document,formId,index,tableId);
+
+				},
+				cancel: function(index){
+				}
+			});
+        }
+
+		// 确认对话框
+		function subConfirmx(mess, href, closed){
+
+			top.layer.confirm(mess, {icon: 3, title:'系统提示'}, function(index){
+				//do something
+				if (typeof href == 'function') {
+					href();
+				}else{
+					$.ajax({
+						type:"post",
+						url:href,
+						dataType:"json",
+						success:function(data){
+							if(data.success) {
+								top.layer.msg(data.str, {icon: 1});
+								window.location.reload();
+							}else {
+								top.layer.msg(data.str, {icon: 0});
+							}
+						}
+					})
+				}
+				top.layer.close(index);
+			});
+			return false;
+		}
+
+		function btnImport(){
+			var parentProId = $("#parentProId").val();
+			top.layer.open({
+				type: 2,
+				area: ['25%', '50%'],
+				title: "上传文件",
+				content: "${ctx}/subProject/subProject/importFile?parentProId="+parentProId+"&projectType=${subProjectInfo.projectType}",
+				//  btn: ['确定', '关闭'],
+				yes: function (index, layero) {
+					var body = top.layer.getChildFrame('body', index);
+					var inputForm = body.find('#inputForm');
+					var top_iframe = top.getActiveTab().attr("name");//获取当前active的tab的iframe
+					inputForm.attr("target", top_iframe);//表单提交成功后,从服务器返回的url在当前tab中展示
+					inputForm.validate();
+					if (inputForm.valid()) {
+						loading("正在提交,请稍等...");
+						inputForm.submit();
+					} else {
+						return;
+					}
+					top.layer.close(index);//关闭对话框。
+				},
+				cancel: function (index) {
+				}
+				,end: function () {
+					location.reload();
+				}
+			});
+		}
+
+	</script>
+	<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>
+</head>
+<body>
+<div class="wrapper wrapper-content">
+	<div class="list-form-tab contentShadow shadowLTR" id="tabDiv">
+		<ul class="list-tabs" >
+			<li><a href="${ctx}/ruralProject/ruralProjectRecords/view?id=${subProjectInfo.parentProId}">项目详情</a></li>
+			<li class="active"><a href="${ctx}/subProject/subProject/list?parentProId=${subProjectInfo.parentProId}&projectType=${subProjectInfo.projectType}">子项目列表</a></li>
+		</ul>
+	</div>
+	<sys:message content="${message}"/>
+	<div class="layui-row">
+		<div class="full-width fl">
+			<div class="layui-row contentShadow shadowLR" id="queryDiv">
+				<form:form id="searchForm" modelAttribute="subProjectInfo" action="${ctx}/subProject/subProject/list?parentProId=${subProjectInfo.parentProId}&projectType=${subProjectInfo.projectType}" method="post" class="form-inline">
+					<input id="parentProId" type="hidden" value="${parentProId}"/>
+					<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 lw6">
+						<div class="layui-item query athird">
+							<label class="layui-form-label">项目定义号:</label>
+							<div class="layui-input-block with-icon">
+								<form:input path="projectId" 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="projectName" 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;" class="lw6">
+						<div class="layui-item query athird ">
+							<label class="layui-form-label">工程编号:</label>
+							<div class="layui-input-block">
+								<form:input path="programmeId" htmlEscape="false" maxlength="255"  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="programmeName" htmlEscape="false" maxlength="255"  class=" form-control layui-input"/>
+							</div>
+						</div>
+						<div class="layui-item query athird ">
+							<label class="layui-form-label">打包时间:</label>
+							<div class="layui-input-block">
+								<input id="beginDate" name="beginDate" placeholder="开始时间" type="text" readonly="readonly" maxlength="20" class="laydate-icondate form-control layer-date layui-input laydate-icon query-group"
+									   value="<fmt:formatDate value="${subProjectInfo.beginDate}" pattern="yyyy-MM-dd"/>"/>
+								</input>
+                                <span class="group-sep">-</span>
+                                <input id="endDate" name="endDate" placeholder="结束时间" type="text" readonly="readonly" maxlength="20" class="laydate-icondate form-control layer-date layui-input laydate-icon query-group"
+                                       value="<fmt:formatDate value="${subProjectInfo.endDate}" pattern="yyyy-MM-dd"/>"/>
+                                </input>
+							</div>
+						</div>
+						<div style="clear:both;"></div>
+					</div>
+				</form:form>
+			</div>
+		</div>
+		<div class="full-width fl">
+			<div class="layui-form contentDetails contentShadow shadowLBR">
+				<div class="nav-btns">
+					<shiro:hasPermission name="ruralProject:ruralProjectRecords:add">
+						<table:subProjectAddRow url="${ctx}/subProject/subProject/form?parentProId=${subProjectInfo.parentProId}" title="项目"></table:subProjectAddRow><!-- 增加按钮 -->
+					</shiro:hasPermission>
+					<shiro:hasPermission name="ruralProject:ruralProjectRecords:export">
+						<button id="btnImport" class="nav-btn nav-btn-import" data-toggle="tooltip" data-placement="left" onclick="btnImport()" title="导入"><i class="fa fa-folder-open-o"></i>&nbsp;导入</button>
+					</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="contentTable1"></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: '#contentTable1'
+            ,page: false
+            ,cols: [[
+                // {checkbox: true, fixed: true},
+                {field:'index',align:'center', title: '序号',width:40}
+                ,{field:'projectId',align:'center', title: '项目定义号', width:150}
+                ,{field:'projectName',align:'center', title: '项目名称',templet:function(d){
+                        return "<a class=\"attention-info\" title=\"" + d.projectName + "\" href=\"javascript:void(0);\" onclick=\"openDialogView('查看项目信息', '${ctx}/subProject/subProject/view?id=" + d.id +"','95%', '95%')\">" + d.projectName + "</a>";
+                    }}
+				,{field:'programmeId',align:'center', title: '工程编号', width:150}
+                ,{field:'programmeName', align:'center',title: '工程名称',templet:function(d){
+                    	return "<span title='"+ d.programmeName +"'>" + d.programmeName + "</span>";
+					}}
+                ,{field:'officeName', align:'center',title: '事务所名称',templet:function(d){
+                        return "<span title=\"" + d.officeName + "\">" + d.officeName + "</span>";
+                    }}
+                ,{field:'officeAuditor',align:'center', title: '事务所审计人员', width:150,templet:function(d){
+                        return "<span title=\"" + d.officeAuditor + "\">" + d.officeAuditor + "</span>";
+                    }}
+                ,{field:'packTime',align:'center', title: '打包时间', width:80}
+                ,{field:'op',align:'center',title:"操作",width:130,templet:function(d){
+                        ////对操作进行初始化
+                        var xml="";
+                        if(d.canedit1 != undefined && d.canedit1 =="1")
+                        {
+							xml+="<a href=\"#\" onclick=\"openDialogre('修改项目', '${ctx}/subProject/subProject/form?id=" + d.id + "','95%', '95%','','inputForm','layui-border-box')\" class=\"op-btn op-btn-edit\" ><i class=\"fa fa-edit\"></i> 修改</a>";
+							xml+="<a href=\"${ctx}/subProject/subProject/delete?id=" + d.id + "\" onclick=\"return subConfirmx('确认要删除该子项目信息吗?', this.href)\" class=\"op-btn op-btn-delete\"><i class=\"fa fa-trash\"></i> 删除</a>";
+                        }
+                        return xml;
+
+                    }}
+            ]]
+            ,data: [
+                <c:if test="${ not empty page.list}">
+                <c:forEach items="${page.list}" var="subProjectInfo" varStatus="index">
+                <c:if test="${index.index != 0}">,</c:if>
+                {
+                    "index":"${index.index+1}"
+                    ,"id":"${subProjectInfo.id}"
+                    ,"projectId":"${subProjectInfo.projectId}"
+                    ,"projectName":"<c:out value="${subProjectInfo.projectName}" escapeXml="true"/>"
+                    ,"programmeId":"${subProjectInfo.programmeId}"
+                    ,"programmeName":"${subProjectInfo.programmeName}"
+                    ,"officeName":"${subProjectInfo.officeName}"
+                    ,"officeAuditor":"${subProjectInfo.officeAuditor}"
+                    ,"packTime":"<fmt:formatDate value="${subProjectInfo.packTime}" pattern="yyyy-MM-dd"/>"
+					,"canedit1":
+							<c:choose>
+								<c:when test="${fns:getUser().id == subProjectInfo.createBy.id}">"1"</c:when>
+								<c:otherwise>"0"</c:otherwise>
+							</c:choose>
+				}
+                </c:forEach>
+                </c:if>
+            ]
+            // ,even: true
+            // ,height: 315
+        });
+    })
+
+    resizeListTable();
+    $("a").on("click",addLinkVisied);
+</script>
+<script>
+    resizeListWindow2();
+    $(window).resize(function(){
+        resizeListWindow2();
+    });
+</script>
+</body>
+</html>

+ 608 - 0
src/main/webapp/webpage/modules/ruralprojectrecords/subProjectInfo/subProjectInfoView.jsp

@@ -0,0 +1,608 @@
+<%@ 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" src="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.js"></script>
+    <script type="text/javascript" src="${ctxStatic}/iCheck/icheck.min.js"></script>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
+    <style>
+        #projectDesc-error{
+            left:0;
+            top:82px;
+        }
+        .layui-layer-dialog{
+            background: red;
+        }
+        td input{
+            margin-left:-10px !important;
+            height: 42px !important;
+        }
+        .disables {
+            pointer-events: none;
+        }
+        .notDisables {
+            pointer-events: all;
+        }
+        .forbidden{
+             background-color:#c2c2c2;
+         }
+
+        .notForbidden{
+
+         }
+        #inputForm input{
+            background-color:#FFFFFF;
+        }
+    </style>
+    <script type="text/javascript">
+        var validateForm;
+        var isMasterClient = true;//是否是委托方
+        var clientCount = 0;
+        function doSubmit(i){//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if(validateForm.form()){
+                var flag = $("#flagFile").val();
+                if(flag == 'false'){
+                    top.layer.msg('附件信息未上传完成,请等待!', {icon: 0});
+                    return;
+                }
+
+                $("#inputForm").submit();
+                return true;
+            }else{
+                parent.layer.msg("信息未填写完整!", {icon: 5});
+            }
+
+            return false;
+        }
+        $(document).ready(function() {
+            var radioVal ;
+            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);
+                    }
+                }
+            });
+        });
+        window.onload=function () {
+            $('#inputForm').find('input').attr('readonly',true);
+        }
+    </script>
+</head>
+<body>
+<div class="single-form">
+    <div class="container">
+        <sys:message content="${message}"/>
+        <form:form id="inputForm" modelAttribute="subProjectInfo" action="${ctx}/subProject/subProject/save" method="post" class="form-horizontal">
+            <form:hidden path="id"/>
+            <form:hidden path="parentProId"/>
+            <input type="hidden" id="flagFile" value="">
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>项目基本信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">项目定义号:</label>
+                    <div class="layui-input-block">
+                        <form:input path="projectId" htmlEscape="false"  class="form-control layui-input" readonly="true"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">项目名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="projectName" htmlEscape="false"  class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">单体工程WBS编号:</label>
+                    <div class="layui-input-block">
+                        <form:input path="wbsNum" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">工程编号:</label>
+                    <div class="layui-input-block">
+                        <form:input path="programmeId" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">工程名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="programmeName" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">审计项目类型:</label>
+                    <div class="layui-input-block">
+                        <form:input path="auditItemsType" htmlEscape="false"  class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">创建人:</label>
+                    <div class="layui-input-block">
+                        <form:input path="createBy.name" htmlEscape="false"  readonly="true"  class="form-control  layui-input"/>
+                        <form:hidden path="createBy.id" htmlEscape="false"   readonly="true"  class="form-control  layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">电压等级:</label>
+                    <div class="layui-input-block">
+                        <form:input path="voltageLevel" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">现场联系人:</label>
+                    <div class="layui-input-block">
+                        <form:input path="onSiteContact" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">联系电话:</label>
+                    <div class="layui-input-block">
+                        <form:input path="contactNumber" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">实际开工时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="actualStartTime" name="actualStartTime" value="<fmt:formatDate value="${subProjectInfo.actualStartTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">实际竣工时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="actualEndTime" name="actualEndTime" value="<fmt:formatDate value="${subProjectInfo.actualEndTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>合同信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工单位名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="constructionUnit" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">合同编号:</label>
+                    <div class="layui-input-block">
+                        <form:input path="contractId" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">合同金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="contractSum" htmlEscape="false" class="form-control layui-input number"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">计划开工时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="planStartTime" name="planStartTime" value="<fmt:formatDate value="${subProjectInfo.planStartTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">计划竣工时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="planEndTime" name="planEndTime" value="<fmt:formatDate value="${subProjectInfo.planEndTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">结算折扣率:</label>
+                    <div class="layui-input-block">
+                        <form:input path="settleDiscountRate" htmlEscape="false" class="form-control layui-input number"/>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>送审信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">土建结算送审金额(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="civilSubmitSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">安装结算送审金额(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="installSubmitSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工费送审金额小计(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="buildSubmitSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">甲供材送审金额(元)结算书中的物资金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="materialSubmitSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>审定信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">土建结算审定金额(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="civilAuthorizeSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">安装结算审定金额(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="installAuthorizeSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工费审定金额小计(元)下浮后金额:</label>
+                    <div class="layui-input-block">
+                        <form:input path="buildAuthorizeSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">甲供材审定金额(元):</label>
+                    <div class="layui-input-block">
+                        <form:input path="materialAuthorizeSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工费核减金额(元):</label>
+                    <div class="layui-input-block">
+                        <form:input path="buildDiscountSum" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工费核减率(%):</label>
+                    <div class="layui-input-block">
+                        <form:input path="buildDiscountRate" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">施工单位诚信扣款(元):</label>
+                    <div class="layui-input-block">
+                        <form:input path="creditDeduction" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">建议结算款(元):</label>
+                    <div class="layui-input-block">
+                        <form:input path="suggestedSettlement" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">是否查看现场:</label>
+                    <div class="layui-input-block">
+                        <select id="hasViewScene" name="hasViewScene" class="form-control editable-select layui-input">
+                            <option value="">请选择</option>
+                            <option value="是" ${subProjectInfo.hasViewScene=='是'?'selected':''}>是</option>
+                            <option value="否" ${subProjectInfo.hasViewScene=='否'?'selected':''}>否</option>
+                        </select>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>审计费信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">审计费(元):</label>
+                    <div class="layui-input-block">
+                        <form:input path="auditFee" htmlEscape="false" class="form-control number layui-input"/>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>审计意见及报告信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">审计部下发意见文号:</label>
+                    <div class="layui-input-block">
+                        <form:input path="optionNum" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">事务所审计报告号(必填):</label>
+                    <div class="layui-input-block">
+                        <form:input path="officeReportNo" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>审计进度信息</h2></div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">事务所名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="officeName" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">事务所审计人员:</label>
+                    <div class="layui-input-block">
+                        <form:input path="officeAuditor" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">打包时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="packTime" name="packTime" value="<fmt:formatDate value="${subProjectInfo.packTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">审计应结束时间:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="planAuditTime" name="planAuditTime" value="<fmt:formatDate value="${subProjectInfo.planAuditTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">审计方式:</label>
+                    <div class="layui-input-block">
+                        <form:input path="auditType" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>备注</h2></div>
+                <div class="layui-item layui-col-sm12 lw7 with-textarea">
+                    <label class="layui-form-label">备注:</label>
+                    <div class="layui-input-block">
+                        <form:textarea path="remarks" htmlEscape="false" rows="4"  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 layui-col-sm6 lw7">
+                    <label class="layui-form-label">审计专职:</label>
+                    <div class="layui-input-block">
+                        <form:input path="auditProfessional" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">提交送审日期:</label>
+                    <div class="layui-input-block">
+                        <input class="laydate-icondate form-control layui-input layer-date laydate-icon" readonly="readonly" id="submitApprovalTime" name="submitApprovalTime" value="<fmt:formatDate value="${subProjectInfo.submitApprovalTime}" pattern="yyyy-MM-dd"/>">
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">送审人:</label>
+                    <div class="layui-input-block">
+                        <form:input path="submitApprovalMan" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">送审部门:</label>
+                    <div class="layui-input-block">
+                        <form:input path="submitApprovalDepartment" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">二级单位:</label>
+                    <div class="layui-input-block">
+                        <form:input path="secondaryUnit" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label">一级单位:</label>
+                    <div class="layui-input-block">
+                        <form:input path="firstLevelUnit" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+                <div class="layui-item layui-col-sm6 lw7">
+                    <label class="layui-form-label double-line">送审单ID(勿动):</label>
+                    <div class="layui-input-block">
+                        <form:input path="submissionFormId" htmlEscape="false" class="form-control layui-input"/>
+                    </div>
+                </div>
+            </div>
+
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>成果文件</h2></div>
+                <div id="addFile_subAttachment" style="display: none" class="upload-progress">
+                    <span id="fileName_subAttachment" ></span>
+                    <span id="_attachment" ></span>
+                    <b><span id="baifenbi_subAttachment" ></span></b>
+                    <div class="progress">
+                        <div id="jindutiao_subAttachment" 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_subAttachment">
+                        <c:forEach items="${subProjectInfo.workAttachments}" var = "workClientAttachment" varStatus="status">
+                            <c:if test="${workClientAttachment.divIdType eq '_subAttachment'}">
+                                <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>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:if>
+                        </c:forEach>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>依据性资料</h2></div>
+                <div id="addFile_subGistdata" style="display: none" class="upload-progress">
+                    <span id="fileName_subGistdata" ></span>
+                    <span id="_gistdata" ></span>
+                    <b><span id="baifenbi_subGistdata" ></span></b>
+                    <div class="progress">
+                        <div id="jindutiao_subGistdata" class="progress-bar" style="width: 0%" aria-valuenow="0">
+                        </div>
+                    </div>
+                </div>
+                <input id="gistdata_file" type="file" name="gistdata_file" multiple="multiple" style="display: none;" onChange="if(this.value)gistdataInsertTitle(this.value);"/>
+                <span id="gistdata_title"></span>
+                <div class="layui-item layui-col-xs12" style="padding:0 16px;">
+                    <table id="gistdata_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_subGistdata">
+                        <c:forEach items="${subProjectInfo.workAttachments}" var = "workClientAttachment" varStatus="status">
+                            <c:if test="${workClientAttachment.divIdType eq '_subGistdata'}">
+                                <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>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:if>
+                        </c:forEach>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+
+            <div class="form-group layui-row">
+                <div class="form-group-label"><h2>其他文件</h2></div>
+                <div id="addFile_subOther" style="display: none" class="upload-progress">
+                    <span id="fileName_subOther" ></span>
+                    <span id="_other" ></span>
+                    <b><span id="baifenbi_subOther" ></span></b>
+                    <div class="progress">
+                        <div id="jindutiao_subOther" class="progress-bar" style="width: 0%" aria-valuenow="0">
+                        </div>
+                    </div>
+                </div>
+                <input id="other_file" type="file" name="other_file" multiple="multiple" style="display: none;" onChange="if(this.value)otherInsertTitle(this.value);"/>
+                <span id="other_title"></span>
+                <div class="layui-item layui-col-xs12" style="padding:0 16px;">
+                    <table id="upTable_other" 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_subOther">
+                        <c:forEach items="${subProjectInfo.workAttachments}" var = "workClientAttachment" varStatus="status">
+                            <c:if test="${workClientAttachment.divIdType eq '_subOther'}">
+                                <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>
+                                        </div>
+                                    </td>
+                                </tr>
+                            </c:if>
+                        </c:forEach>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+            <div class="form-group layui-row page-end"></div>
+        </form:form>
+    </div>
+</div>
+</body>
+</html>