浏览代码

新的需求

jz.kai 1 年之前
父节点
当前提交
89522ee159
共有 27 个文件被更改,包括 2753 次插入8 次删除
  1. 21 0
      common/src/main/java/com/jpsoft/excellent/modules/base/dao/SpecialAttachmentDAO.java
  2. 20 0
      common/src/main/java/com/jpsoft/excellent/modules/base/dao/SpecialOpinionDAO.java
  3. 18 0
      common/src/main/java/com/jpsoft/excellent/modules/base/dao/SpecialStepDAO.java
  4. 20 0
      common/src/main/java/com/jpsoft/excellent/modules/base/dao/SpecialStepStatusDAO.java
  5. 28 0
      common/src/main/java/com/jpsoft/excellent/modules/base/dto/SpecialOpinionReportDTO.java
  6. 33 0
      common/src/main/java/com/jpsoft/excellent/modules/base/entity/SpecialAttachment.java
  7. 82 0
      common/src/main/java/com/jpsoft/excellent/modules/base/entity/SpecialOpinion.java
  8. 38 0
      common/src/main/java/com/jpsoft/excellent/modules/base/entity/SpecialStep.java
  9. 48 0
      common/src/main/java/com/jpsoft/excellent/modules/base/entity/SpecialStepStatus.java
  10. 21 0
      common/src/main/java/com/jpsoft/excellent/modules/base/service/SpecialAttachmentService.java
  11. 19 0
      common/src/main/java/com/jpsoft/excellent/modules/base/service/SpecialOpinionService.java
  12. 17 0
      common/src/main/java/com/jpsoft/excellent/modules/base/service/SpecialStepService.java
  13. 19 0
      common/src/main/java/com/jpsoft/excellent/modules/base/service/SpecialStepStatusService.java
  14. 82 0
      common/src/main/java/com/jpsoft/excellent/modules/base/service/impl/SpecialAttachmentServiceImpl.java
  15. 85 0
      common/src/main/java/com/jpsoft/excellent/modules/base/service/impl/SpecialOpinionServiceImpl.java
  16. 70 0
      common/src/main/java/com/jpsoft/excellent/modules/base/service/impl/SpecialStepServiceImpl.java
  17. 82 0
      common/src/main/java/com/jpsoft/excellent/modules/base/service/impl/SpecialStepStatusServiceImpl.java
  18. 1 1
      common/src/main/resources/mapper/base/Area.xml
  19. 105 0
      common/src/main/resources/mapper/base/SpecialAttachment.xml
  20. 254 0
      common/src/main/resources/mapper/base/SpecialOpinion.xml
  21. 91 0
      common/src/main/resources/mapper/base/SpecialStep.xml
  22. 127 0
      common/src/main/resources/mapper/base/SpecialStepStatus.xml
  23. 1144 0
      web/src/main/java/com/jpsoft/excellent/modules/base/controller/SpecialOpinionController.java
  24. 3 1
      web/src/main/java/com/jpsoft/excellent/modules/open/FeedbackOpinionApiController.java
  25. 1 1
      web/src/main/java/com/jpsoft/excellent/modules/open/OfficeOpinionApiController.java
  26. 319 0
      web/src/main/java/com/jpsoft/excellent/modules/open/SpecialOpinionApiController.java
  27. 5 5
      web/src/main/resources/application-dev.yml

+ 21 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/dao/SpecialAttachmentDAO.java

@@ -0,0 +1,21 @@
+package com.jpsoft.excellent.modules.base.dao;
+
+import com.jpsoft.excellent.modules.base.entity.SpecialAttachment;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Map;
+
+@Repository
+public interface SpecialAttachmentDAO {
+	int insert(SpecialAttachment entity);
+	int update(SpecialAttachment entity);
+	int exist(String id);
+	SpecialAttachment get(String id);
+	int delete(String id);
+	List<SpecialAttachment> list();
+	List<SpecialAttachment> search(Map<String,Object> searchParams, List<Sort> sortList);
+	List<SpecialAttachment> findListBySpecialOpinionId(String specialOpinionId, String attachmentType);
+	SpecialAttachment getBySpecialOpinionId(String id);
+}

+ 20 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/dao/SpecialOpinionDAO.java

@@ -0,0 +1,20 @@
+package com.jpsoft.excellent.modules.base.dao;
+
+import java.util.List;
+import org.springframework.stereotype.Repository;
+import com.jpsoft.excellent.modules.base.entity.SpecialOpinion;
+import java.util.Map;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+
+@Repository
+public interface SpecialOpinionDAO {
+	int insert(SpecialOpinion entity);
+	int update(SpecialOpinion entity);
+	int exist(String id);
+	SpecialOpinion get(String id);
+	int delete(String id);
+	List<SpecialOpinion> list();
+	List<SpecialOpinion> search(Map<String,Object> searchParams,List<Sort> sortList);
+	String getLastSort(String date);
+	List<SpecialOpinion> searchTodo(Map<String,Object> searchParams,List<Sort> sortList);
+}

+ 18 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/dao/SpecialStepDAO.java

@@ -0,0 +1,18 @@
+package com.jpsoft.excellent.modules.base.dao;
+
+import java.util.List;
+import org.springframework.stereotype.Repository;
+import com.jpsoft.excellent.modules.base.entity.SpecialStep;
+import java.util.Map;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+
+@Repository
+public interface SpecialStepDAO {
+	int insert(SpecialStep entity);
+	int update(SpecialStep entity);
+	int exist(String id);
+	SpecialStep get(String id);
+	int delete(String id);
+	List<SpecialStep> list();
+	List<SpecialStep> search(Map<String,Object> searchParams,List<Sort> sortList);
+}

+ 20 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/dao/SpecialStepStatusDAO.java

@@ -0,0 +1,20 @@
+package com.jpsoft.excellent.modules.base.dao;
+
+import java.util.List;
+import org.springframework.stereotype.Repository;
+import com.jpsoft.excellent.modules.base.entity.SpecialStepStatus;
+import java.util.Map;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+
+@Repository
+public interface SpecialStepStatusDAO {
+	int insert(SpecialStepStatus entity);
+	int update(SpecialStepStatus entity);
+	int exist(String id);
+	SpecialStepStatus get(String id);
+	int delete(String id);
+	List<SpecialStepStatus> list();
+	List<SpecialStepStatus> search(Map<String,Object> searchParams,List<Sort> sortList);
+	List<SpecialStepStatus> findByList(String specialOpinionId, Boolean status);
+	List<String> findPhoneByRemind(String date);
+}

+ 28 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/dto/SpecialOpinionReportDTO.java

@@ -0,0 +1,28 @@
+package com.jpsoft.excellent.modules.base.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@ApiModel(value = "SpecialOpinionReport的实体类")
+public class SpecialOpinionReportDTO {
+    @ApiModelProperty(value = "区域")
+    private String area;
+    @ApiModelProperty(value = "满意")
+    private Integer countMY;
+    @ApiModelProperty(value = "不满意")
+    private Integer countBMY;
+    @ApiModelProperty(value = "已处理")
+    private Integer countYCL;
+    @ApiModelProperty(value = "未处理")
+    private Integer countWCL;
+    @ApiModelProperty(value = "已确认")
+    private Integer countYQR;
+    @ApiModelProperty(value = "未确认")
+    private Integer countWQR;
+
+    private List<SpecialOpinionReportDTO> tableData;
+}

+ 33 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/entity/SpecialAttachment.java

@@ -0,0 +1,33 @@
+package com.jpsoft.excellent.modules.base.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+@ApiModel(value = "base_Special_attachment的实体类")
+public class SpecialAttachment {
+        @ApiModelProperty(value = "编号")
+    private String id;
+        @ApiModelProperty(value = "反馈意见编号")
+    private String specialOpinionId;
+        @ApiModelProperty(value = "附件类型")
+    private String attachmentType;
+        @ApiModelProperty(value = "附件标题")
+    private String attachmentTitle;
+        @ApiModelProperty(value = "附件路径")
+    private String attachmentUrl;
+        @ApiModelProperty(value = "序号")
+    private Integer sortNo;
+        @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone ="GMT+8")
+	    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+        @ApiModelProperty(value = "创建人")
+    private String createBy;
+}

+ 82 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/entity/SpecialOpinion.java

@@ -0,0 +1,82 @@
+package com.jpsoft.excellent.modules.base.entity;
+
+import java.util.Date;
+import java.util.List;
+
+import com.jpsoft.excellent.modules.base.dto.AttachmentDTO;
+import org.springframework.format.annotation.DateTimeFormat;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "base_Special_opinion的实体类")
+public class SpecialOpinion {
+        @ApiModelProperty(value = "编号")
+    private String id;
+        @ApiModelProperty(value = "序号")
+    private String sort;
+        @ApiModelProperty(value = "联系人")
+    private String connect;
+        @ApiModelProperty(value = "联系电话")
+    private String connectPhone;
+        @ApiModelProperty(value = "站点编号")
+    private String workStationId;
+        @ApiModelProperty(value = "窗口")
+    private String window;
+        @ApiModelProperty(value = "是否满意")
+    private Boolean isSatisfied;
+        @ApiModelProperty(value = "处理进度")
+    private Boolean opinionStatus;
+        @ApiModelProperty(value = "确认状态")
+    private Integer confirmStatus;
+        @ApiModelProperty(value = "原因")
+    private String cause;
+        @ApiModelProperty(value = "内容")
+    private String content;
+        @ApiModelProperty(value = "附件")
+    private String appendix;
+    private String[] appendixList;
+        @ApiModelProperty(value = "处理情况")
+    private String contentAttachment;
+    @DateTimeFormat(pattern="yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd",timezone ="GMT+8")
+    @ApiModelProperty(value = "办理期限")
+    private Date allotedDate;
+        @ApiModelProperty(value = "是否删除")
+    private Boolean delFlag;
+        @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone ="GMT+8")
+	    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+        @ApiModelProperty(value = "创建人")
+    private String createBy;
+        @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone ="GMT+8")
+	    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+        @ApiModelProperty(value = "更新人")
+    private String updateBy;
+
+        @ApiModelProperty(value = "区域")
+    private String areaId;
+    private String areaName;
+        @ApiModelProperty(value = "站点名称")
+    private String stationName;
+        @ApiModelProperty(value = "是否包含下级单位")
+    private Boolean areaSubordinate;
+
+        @ApiModelProperty(value = "附件列表")
+    private List<AttachmentDTO> attList;
+        @ApiModelProperty(value = "图片列表")
+    private List<AttachmentDTO> picList;
+        @ApiModelProperty(value = "图片路径数组")
+    private String[] picUrlList;
+        @ApiModelProperty(value = "处理完成")
+    private Boolean isProcessed;
+        @ApiModelProperty(value = "站点回复")
+    private List<SpecialStepStatus> stepStatusList;
+    @ApiModelProperty(value = "步进状态编号")
+    private String stepStatusId;
+}

+ 38 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/entity/SpecialStep.java

@@ -0,0 +1,38 @@
+package com.jpsoft.excellent.modules.base.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.math.BigDecimal;
+import org.springframework.format.annotation.DateTimeFormat;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "base_Special_step的实体类")
+public class SpecialStep {
+        @ApiModelProperty(value = "编号")
+    private String id;
+        @ApiModelProperty(value = "反馈信息编号")
+    private String specialOpinionId;
+        @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone ="GMT+8")
+	    @ApiModelProperty(value = "办理期限")
+    private Date allotedDate;
+        @ApiModelProperty(value = "是否删除")
+    private Boolean delFlag;
+        @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone ="GMT+8")
+	    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+        @ApiModelProperty(value = "创建人")
+    private String createBy;
+        @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone ="GMT+8")
+	    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+        @ApiModelProperty(value = "更新人")
+    private String updateBy;
+}

+ 48 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/entity/SpecialStepStatus.java

@@ -0,0 +1,48 @@
+package com.jpsoft.excellent.modules.base.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.math.BigDecimal;
+import org.springframework.format.annotation.DateTimeFormat;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "base_Special_step_status的实体类")
+public class SpecialStepStatus {
+        @ApiModelProperty(value = "编号")
+    private String id;
+        @ApiModelProperty(value = "步进编号")
+    private String specialStepId;
+        @ApiModelProperty(value = "交办站点")
+    private String orgId;
+    private String orgName;
+        @ApiModelProperty(value = "回复人")
+    private String userId;
+    private String userName;
+        @ApiModelProperty(value = "回复内容")
+    private String content;
+        @ApiModelProperty(value = "完成状态(0:未完成 1:已完成)")
+    private Boolean status;
+        @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone ="GMT+8")
+	    @ApiModelProperty(value = "办理期限")
+    private Date allotedDate;
+        @ApiModelProperty(value = "是否删除")
+    private Boolean delFlag;
+        @DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone ="GMT+8")
+	    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+        @ApiModelProperty(value = "创建人")
+    private String createBy;
+        @DateTimeFormat(pattern="yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd",timezone ="GMT+8")
+	    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+        @ApiModelProperty(value = "更新人")
+    private String updateBy;
+}

+ 21 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/service/SpecialAttachmentService.java

@@ -0,0 +1,21 @@
+package com.jpsoft.excellent.modules.base.service;
+
+import com.github.pagehelper.Page;
+import com.jpsoft.excellent.modules.base.entity.SpecialAttachment;
+import com.jpsoft.excellent.modules.base.entity.MessageAttachment;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+
+import java.util.List;
+import java.util.Map;
+
+public interface SpecialAttachmentService {
+	SpecialAttachment get(String id);
+	boolean exist(String id);
+	int insert(SpecialAttachment model);
+	int update(SpecialAttachment model);
+	int delete(String id);
+	List<SpecialAttachment> list();
+	Page<SpecialAttachment> pageSearch(Map<String, Object> searchParams, int pageNum, int pageSize, boolean count, List<Sort> sortList);
+	List<SpecialAttachment> findListBySpecialOpinionId(String specialOpinionId, String attachmentType);
+	SpecialAttachment getBySpecialOpinionId(String specialOpinionId);
+}

+ 19 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/service/SpecialOpinionService.java

@@ -0,0 +1,19 @@
+package com.jpsoft.excellent.modules.base.service;
+
+import java.util.List;
+import java.util.Map;
+import com.jpsoft.excellent.modules.base.entity.SpecialOpinion;
+import com.github.pagehelper.Page;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+
+public interface SpecialOpinionService {
+	SpecialOpinion get(String id);
+	boolean exist(String id);
+	int insert(SpecialOpinion model);
+	int update(SpecialOpinion model);
+	int delete(String id);
+	List<SpecialOpinion> list();
+	Page<SpecialOpinion> pageSearch(Map<String, Object> searchParams,int pageNum,int pageSize,boolean count,List<Sort> sortList);
+	String getLastSort(String date);
+	Page<SpecialOpinion> pageSearchTodo(Map<String, Object> searchParams,int pageNum,int pageSize,boolean count,List<Sort> sortList);
+}

+ 17 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/service/SpecialStepService.java

@@ -0,0 +1,17 @@
+package com.jpsoft.excellent.modules.base.service;
+
+import java.util.List;
+import java.util.Map;
+import com.jpsoft.excellent.modules.base.entity.SpecialStep;
+import com.github.pagehelper.Page;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+
+public interface SpecialStepService {
+	SpecialStep get(String id);
+	boolean exist(String id);
+	int insert(SpecialStep model);
+	int update(SpecialStep model);
+	int delete(String id);
+	List<SpecialStep> list();
+	Page<SpecialStep> pageSearch(Map<String, Object> searchParams,int pageNum,int pageSize,boolean count,List<Sort> sortList);
+}

+ 19 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/service/SpecialStepStatusService.java

@@ -0,0 +1,19 @@
+package com.jpsoft.excellent.modules.base.service;
+
+import java.util.List;
+import java.util.Map;
+import com.jpsoft.excellent.modules.base.entity.SpecialStepStatus;
+import com.github.pagehelper.Page;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+
+public interface SpecialStepStatusService {
+	SpecialStepStatus get(String id);
+	boolean exist(String id);
+	int insert(SpecialStepStatus model);
+	int update(SpecialStepStatus model);
+	int delete(String id);
+	List<SpecialStepStatus> list();
+	Page<SpecialStepStatus> pageSearch(Map<String, Object> searchParams,int pageNum,int pageSize,boolean count,List<Sort> sortList);
+	List<SpecialStepStatus> findByList(String specialOpinionId, Boolean status);
+	List<String> findPhoneByRemind(String date);
+}

+ 82 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/service/impl/SpecialAttachmentServiceImpl.java

@@ -0,0 +1,82 @@
+package com.jpsoft.excellent.modules.base.service.impl;
+
+import com.github.pagehelper.Page;
+import com.github.pagehelper.PageHelper;
+import com.jpsoft.excellent.modules.base.dao.SpecialAttachmentDAO;
+import com.jpsoft.excellent.modules.base.entity.SpecialAttachment;
+import com.jpsoft.excellent.modules.base.service.SpecialAttachmentService;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+@Transactional
+@Component(value="specialAttachmentService")
+public class SpecialAttachmentServiceImpl implements SpecialAttachmentService {
+	@Resource(name="specialAttachmentDAO")
+	private SpecialAttachmentDAO specialAttachmentDAO;
+
+	@Override
+	public SpecialAttachment get(String id) {
+		// TODO Auto-generated method stub
+		return specialAttachmentDAO.get(id);
+	}
+
+	@Override
+	public int insert(SpecialAttachment model) {
+		// TODO Auto-generated method stub
+		//model.setId(UUID.randomUUID().toString());
+		
+		return specialAttachmentDAO.insert(model);
+	}
+
+	@Override
+	public int update(SpecialAttachment model) {
+		// TODO Auto-generated method stub
+		return specialAttachmentDAO.update(model);
+	}
+
+	@Override
+	public int delete(String id) {
+		// TODO Auto-generated method stub
+		return specialAttachmentDAO.delete(id);
+	}
+
+	@Override
+	public boolean exist(String id) {
+		// TODO Auto-generated method stub
+		int count = specialAttachmentDAO.exist(id);
+		
+		return count > 0 ? true : false;
+	}
+	
+	@Override
+	public List<SpecialAttachment> list() {
+		// TODO Auto-generated method stub
+		return specialAttachmentDAO.list();
+	}
+
+	@Override
+	public Page<SpecialAttachment> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize, boolean count, List<Sort> sortList) {
+		Page<SpecialAttachment> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
+			specialAttachmentDAO.search(searchParams,sortList);
+		});
+
+		return page;
+	}
+
+	@Override
+	public List<SpecialAttachment> findListBySpecialOpinionId(String specialOpinionId, String attachmentType) {
+		// TODO Auto-generated method stub
+		return specialAttachmentDAO.findListBySpecialOpinionId(specialOpinionId, attachmentType);
+	}
+
+	@Override
+	public SpecialAttachment getBySpecialOpinionId(String specialOpinionId) {
+		// TODO Auto-generated method stub
+		return specialAttachmentDAO.getBySpecialOpinionId(specialOpinionId);
+	}
+}

+ 85 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/service/impl/SpecialOpinionServiceImpl.java

@@ -0,0 +1,85 @@
+package com.jpsoft.excellent.modules.base.service.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.annotation.Resource;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import com.jpsoft.excellent.modules.base.dao.SpecialOpinionDAO;
+import com.jpsoft.excellent.modules.base.entity.SpecialOpinion;
+import com.jpsoft.excellent.modules.base.service.SpecialOpinionService;
+import com.github.pagehelper.Page;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+import com.github.pagehelper.PageHelper;
+
+@Transactional
+@Component(value="specialOpinionService")
+public class SpecialOpinionServiceImpl implements SpecialOpinionService {
+	@Resource(name="specialOpinionDAO")
+	private SpecialOpinionDAO specialOpinionDAO;
+
+	@Override
+	public SpecialOpinion get(String id) {
+		// TODO Auto-generated method stub
+		return specialOpinionDAO.get(id);
+	}
+
+	@Override
+	public int insert(SpecialOpinion model) {
+		// TODO Auto-generated method stub
+		//model.setId(UUID.randomUUID().toString());
+		
+		return specialOpinionDAO.insert(model);
+	}
+
+	@Override
+	public int update(SpecialOpinion model) {
+		// TODO Auto-generated method stub
+		return specialOpinionDAO.update(model);		
+	}
+
+	@Override
+	public int delete(String id) {
+		// TODO Auto-generated method stub
+		return specialOpinionDAO.delete(id);
+	}
+
+	@Override
+	public boolean exist(String id) {
+		// TODO Auto-generated method stub
+		int count = specialOpinionDAO.exist(id);
+		
+		return count > 0 ? true : false;
+	}
+	
+	@Override
+	public List<SpecialOpinion> list() {
+		// TODO Auto-generated method stub
+		return specialOpinionDAO.list();
+	}
+		
+	@Override
+	public Page<SpecialOpinion> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize,boolean count,List<Sort> sortList) {
+        Page<SpecialOpinion> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
+            specialOpinionDAO.search(searchParams,sortList);
+        });
+        
+        return page;
+	}
+
+	@Override
+	public String getLastSort(String date) {
+		// TODO Auto-generated method stub
+		return specialOpinionDAO.getLastSort(date);
+	}
+
+	@Override
+	public Page<SpecialOpinion> pageSearchTodo(Map<String, Object> searchParams, int pageNumber, int pageSize,boolean count,List<Sort> sortList) {
+		Page<SpecialOpinion> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
+			specialOpinionDAO.searchTodo(searchParams,sortList);
+		});
+
+		return page;
+	}
+}

+ 70 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/service/impl/SpecialStepServiceImpl.java

@@ -0,0 +1,70 @@
+package com.jpsoft.excellent.modules.base.service.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.annotation.Resource;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import com.jpsoft.excellent.modules.base.dao.SpecialStepDAO;
+import com.jpsoft.excellent.modules.base.entity.SpecialStep;
+import com.jpsoft.excellent.modules.base.service.SpecialStepService;
+import com.github.pagehelper.Page;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+import com.github.pagehelper.PageHelper;
+
+@Transactional
+@Component(value="specialStepService")
+public class SpecialStepServiceImpl implements SpecialStepService {
+	@Resource(name="specialStepDAO")
+	private SpecialStepDAO specialStepDAO;
+
+	@Override
+	public SpecialStep get(String id) {
+		// TODO Auto-generated method stub
+		return specialStepDAO.get(id);
+	}
+
+	@Override
+	public int insert(SpecialStep model) {
+		// TODO Auto-generated method stub
+		//model.setId(UUID.randomUUID().toString());
+		
+		return specialStepDAO.insert(model);
+	}
+
+	@Override
+	public int update(SpecialStep model) {
+		// TODO Auto-generated method stub
+		return specialStepDAO.update(model);		
+	}
+
+	@Override
+	public int delete(String id) {
+		// TODO Auto-generated method stub
+		return specialStepDAO.delete(id);
+	}
+
+	@Override
+	public boolean exist(String id) {
+		// TODO Auto-generated method stub
+		int count = specialStepDAO.exist(id);
+		
+		return count > 0 ? true : false;
+	}
+	
+	@Override
+	public List<SpecialStep> list() {
+		// TODO Auto-generated method stub
+		return specialStepDAO.list();
+	}
+		
+	@Override
+	public Page<SpecialStep> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize,boolean count,List<Sort> sortList) {
+        Page<SpecialStep> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
+            specialStepDAO.search(searchParams,sortList);
+        });
+        
+        return page;
+	}
+}

+ 82 - 0
common/src/main/java/com/jpsoft/excellent/modules/base/service/impl/SpecialStepStatusServiceImpl.java

@@ -0,0 +1,82 @@
+package com.jpsoft.excellent.modules.base.service.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.annotation.Resource;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import com.jpsoft.excellent.modules.base.dao.SpecialStepStatusDAO;
+import com.jpsoft.excellent.modules.base.entity.SpecialStepStatus;
+import com.jpsoft.excellent.modules.base.service.SpecialStepStatusService;
+import com.github.pagehelper.Page;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+import com.github.pagehelper.PageHelper;
+
+@Transactional
+@Component(value="specialStepStatusService")
+public class SpecialStepStatusServiceImpl implements SpecialStepStatusService {
+	@Resource(name="specialStepStatusDAO")
+	private SpecialStepStatusDAO specialStepStatusDAO;
+
+	@Override
+	public SpecialStepStatus get(String id) {
+		// TODO Auto-generated method stub
+		return specialStepStatusDAO.get(id);
+	}
+
+	@Override
+	public int insert(SpecialStepStatus model) {
+		// TODO Auto-generated method stub
+		//model.setId(UUID.randomUUID().toString());
+		
+		return specialStepStatusDAO.insert(model);
+	}
+
+	@Override
+	public int update(SpecialStepStatus model) {
+		// TODO Auto-generated method stub
+		return specialStepStatusDAO.update(model);		
+	}
+
+	@Override
+	public int delete(String id) {
+		// TODO Auto-generated method stub
+		return specialStepStatusDAO.delete(id);
+	}
+
+	@Override
+	public boolean exist(String id) {
+		// TODO Auto-generated method stub
+		int count = specialStepStatusDAO.exist(id);
+		
+		return count > 0 ? true : false;
+	}
+	
+	@Override
+	public List<SpecialStepStatus> list() {
+		// TODO Auto-generated method stub
+		return specialStepStatusDAO.list();
+	}
+		
+	@Override
+	public Page<SpecialStepStatus> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize,boolean count,List<Sort> sortList) {
+        Page<SpecialStepStatus> page = PageHelper.startPage(pageNumber,pageSize,count).doSelectPage(()->{
+            specialStepStatusDAO.search(searchParams,sortList);
+        });
+        
+        return page;
+	}
+
+	@Override
+	public List<SpecialStepStatus> findByList(String specialOpinionId, Boolean status) {
+		// TODO Auto-generated method stub
+		return specialStepStatusDAO.findByList(specialOpinionId, status);
+	}
+
+	@Override
+	public List<String> findPhoneByRemind(String date) {
+		// TODO Auto-generated method stub
+		return specialStepStatusDAO.findPhoneByRemind(date);
+	}
+}

+ 1 - 1
common/src/main/resources/mapper/base/Area.xml

@@ -90,7 +90,7 @@ id_,parent_id,code_,name_,del_flag,create_time,create_by,update_time,update_by
 				and parent_id IS NULL
 			</if>
 			<if test="searchParams.name">
-				and name_ LIKE ${searchParams.name}
+				and name_ LIKE #{searchParams.name}
 			</if>
 		</where>
 		<foreach item="sort" collection="sortList"  open="order by" separator=",">

+ 105 - 0
common/src/main/resources/mapper/base/SpecialAttachment.xml

@@ -0,0 +1,105 @@
+<?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">
+<!-- namespace必须指向DAO接口 -->
+<mapper namespace="com.jpsoft.excellent.modules.base.dao.SpecialAttachmentDAO">
+	<resultMap id="SpecialAttachmentMap" type="com.jpsoft.excellent.modules.base.entity.SpecialAttachment">
+		<id property="id" column="id_" />
+		<result property="specialOpinionId" column="special_opinion_id" />
+		<result property="attachmentType" column="attachment_type" />
+		<result property="attachmentTitle" column="attachment_title" />
+		<result property="attachmentUrl" column="attachment_url" />
+		<result property="sortNo" column="sort_no" />
+		<result property="createTime" column="create_time" />
+		<result property="createBy" column="create_by" />
+	</resultMap>
+	<insert id="insert" parameterType="com.jpsoft.excellent.modules.base.entity.SpecialAttachment">
+	<!--
+	<selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id">
+		select sys_guid() from dual
+	</selectKey>
+	-->
+	<![CDATA[
+		insert into base_special_attachment
+	    (id_,special_opinion_id,attachment_type,attachment_title,attachment_url,sort_no,create_time,create_by)
+		values
+		(
+#{id,jdbcType=VARCHAR}
+,#{specialOpinionId,jdbcType=VARCHAR}
+,#{attachmentType,jdbcType=VARCHAR}
+,#{attachmentTitle,jdbcType=VARCHAR}
+,#{attachmentUrl,jdbcType=VARCHAR}
+,#{sortNo,jdbcType= NUMERIC }
+,#{createTime,jdbcType= TIMESTAMP }
+,#{createBy,jdbcType=VARCHAR}
+		)
+	]]>
+	</insert>
+	<delete id="delete" parameterType="string">
+		delete from base_special_attachment where id_=#{id,jdbcType=VARCHAR}
+	</delete>
+	<update id="update" parameterType="com.jpsoft.excellent.modules.base.entity.SpecialAttachment">
+		update base_special_attachment
+		<set>
+				<if test="specialOpinionId!=null">
+		special_opinion_id=#{specialOpinionId,jdbcType=VARCHAR},
+		</if>
+				<if test="attachmentType!=null">
+		attachment_type=#{attachmentType,jdbcType=VARCHAR},
+		</if>
+				<if test="attachmentTitle!=null">
+		attachment_title=#{attachmentTitle,jdbcType=VARCHAR},
+		</if>
+				<if test="attachmentUrl!=null">
+		attachment_url=#{attachmentUrl,jdbcType=VARCHAR},
+		</if>
+				<if test="sortNo!=null">
+		sort_no=#{sortNo,jdbcType= NUMERIC },
+		</if>
+				<if test="createTime!=null">
+		create_time=#{createTime,jdbcType= TIMESTAMP },
+		</if>
+				<if test="createBy!=null">
+		create_by=#{createBy,jdbcType=VARCHAR},
+		</if>
+		</set>
+	where id_=#{id}
+	</update>
+	<select id="get" parameterType="string" resultMap="SpecialAttachmentMap">
+		select * from base_special_attachment where id_=#{0}
+	</select>
+	<select id="exist" parameterType="string" resultType="int">
+		select count(*) from base_special_attachment where id_=#{0}
+	</select>
+	<select id="list" resultMap="SpecialAttachmentMap">
+		select * from base_special_attachment
+	</select>
+	<select id="search" parameterType="hashmap" resultMap="SpecialAttachmentMap">
+		<![CDATA[
+			select * from base_special_attachment
+		]]>
+		<where>
+			<if test="searchParams.id != null">
+				and ID_ like #{searchParams.id}
+			</if>
+		</where>
+		<foreach item="sort" collection="sortList"  open="order by" separator=",">
+			${sort.name} ${sort.order}
+		</foreach>
+	</select>
+	<select id="findListBySpecialOpinionId" parameterType="string" resultMap="SpecialAttachmentMap">
+		select * from base_special_attachment
+		<where>
+			<if test="specialOpinionId != null">
+				and special_opinion_id=#{specialOpinionId}
+			</if>
+			<if test="attachmentType != null">
+				and attachment_type=#{attachmentType}
+			</if>
+		</where>
+		order by sort_no asc
+	</select>
+	<select id="getBySpecialOpinionId" parameterType="string" resultMap="SpecialAttachmentMap">
+		select DISTINCT content_ from base_special_attachment where special_opinion_id=#{0}
+	</select>
+</mapper>

+ 254 - 0
common/src/main/resources/mapper/base/SpecialOpinion.xml

@@ -0,0 +1,254 @@
+<?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">
+<!-- namespace必须指向DAO接口 -->
+<mapper namespace="com.jpsoft.excellent.modules.base.dao.SpecialOpinionDAO">
+	<resultMap id="SpecialOpinionMap" type="com.jpsoft.excellent.modules.base.entity.SpecialOpinion">
+		<id property="id" column="id_" />
+		<result property="sort" column="sort_" />
+		<result property="connect" column="connect_" />
+		<result property="connectPhone" column="connect_phone" />
+		<result property="workStationId" column="work_station_id" />
+		<result property="window" column="window_" />
+		<result property="isSatisfied" column="is_satisfied" />
+		<result property="opinionStatus" column="opinion_status" />
+		<result property="confirmStatus" column="confirm_status" />
+		<result property="cause" column="cause_" />
+		<result property="content" column="content_" />
+		<result property="appendix" column="appendix_" />
+		<result property="contentAttachment" column="content_attachment" />
+		<result property="allotedDate" column="alloted_date" />
+		<result property="delFlag" column="del_flag" />
+		<result property="createTime" column="create_time" />
+		<result property="createBy" column="create_by" />
+		<result property="updateTime" column="update_time" />
+		<result property="updateBy" column="update_by" />
+
+		<result property="areaId" column="area_id" />
+		<result property="stationName" column="station_name" />
+		<result property="stepStatusId" column="step_status_id" />
+	</resultMap>
+	<insert id="insert" parameterType="com.jpsoft.excellent.modules.base.entity.SpecialOpinion">
+	<!--
+	<selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id">
+		select sys_guid() from dual
+	</selectKey>
+	-->
+	<![CDATA[
+		insert into base_special_opinion
+	    (id_,sort_,connect_,connect_phone,work_station_id,window_,is_satisfied,opinion_status,confirm_status,cause_,content_,appendix_,content_attachment,del_flag,create_time,create_by,update_time,update_by,alloted_date)
+		values
+		(
+#{id,jdbcType=VARCHAR}
+,#{sort,jdbcType=VARCHAR}
+,#{connect,jdbcType=VARCHAR}
+,#{connectPhone,jdbcType=VARCHAR}
+,#{workStationId,jdbcType=VARCHAR}
+,#{window,jdbcType=VARCHAR}
+,#{isSatisfied,jdbcType= NUMERIC }
+,#{opinionStatus,jdbcType= NUMERIC }
+,#{confirmStatus,jdbcType= NUMERIC }
+,#{cause,jdbcType=VARCHAR}
+,#{content,jdbcType=VARCHAR}
+,#{appendix,jdbcType=VARCHAR}
+,#{contentAttachment,jdbcType=VARCHAR}
+,#{delFlag,jdbcType= NUMERIC }
+,#{createTime,jdbcType= TIMESTAMP }
+,#{createBy,jdbcType=VARCHAR}
+,#{updateTime,jdbcType= TIMESTAMP }
+,#{updateBy,jdbcType=VARCHAR}
+,#{allotedDate,jdbcType=VARCHAR}
+		)
+	]]>
+	</insert>
+	<delete id="delete" parameterType="string">
+		delete from base_special_opinion where id_=#{id,jdbcType=VARCHAR}
+	</delete>
+	<update id="update" parameterType="com.jpsoft.excellent.modules.base.entity.SpecialOpinion">
+		update base_special_opinion
+		<set>
+				<if test="sort!=null">
+		sort_=#{sort,jdbcType=VARCHAR},
+		</if>
+				<if test="connect!=null">
+		connect_=#{connect,jdbcType=VARCHAR},
+		</if>
+				<if test="connectPhone!=null">
+		connect_phone=#{connectPhone,jdbcType=VARCHAR},
+		</if>
+				<if test="workStationId!=null">
+		work_station_id=#{workStationId,jdbcType=VARCHAR},
+		</if>
+				<if test="window!=null">
+		window_=#{window,jdbcType=VARCHAR},
+		</if>
+				<if test="isSatisfied!=null">
+		is_satisfied=#{isSatisfied,jdbcType= NUMERIC },
+		</if>
+			<if test="opinionStatus!=null">
+		opinion_status=#{opinionStatus,jdbcType= NUMERIC },
+		</if>
+			<if test="confirmStatus!=null">
+		confirm_status=#{confirmStatus,jdbcType= NUMERIC },
+		</if>
+				<if test="cause!=null">
+		cause_=#{cause,jdbcType=VARCHAR},
+		</if>
+				<if test="content!=null">
+		content_=#{content,jdbcType=VARCHAR},
+		</if>
+				<if test="appendix!=null">
+		appendix_=#{appendix,jdbcType=VARCHAR},
+		</if>
+				<if test="contentAttachment!=null">
+		content_attachment=#{contentAttachment,jdbcType=VARCHAR},
+		</if>
+				<if test="delFlag!=null">
+		del_flag=#{delFlag,jdbcType= NUMERIC },
+		</if>
+				<if test="createTime!=null">
+		create_time=#{createTime,jdbcType= TIMESTAMP },
+		</if>
+				<if test="createBy!=null">
+		create_by=#{createBy,jdbcType=VARCHAR},
+		</if>
+				<if test="updateTime!=null">
+		update_time=#{updateTime,jdbcType= TIMESTAMP },
+		</if>
+				<if test="updateBy!=null">
+		update_by=#{updateBy,jdbcType=VARCHAR},
+		</if>
+			<if test="allotedDate!=null">
+				alloted_date=#{allotedDate,jdbcType=VARCHAR},
+			</if>
+		</set>
+	where id_=#{id}
+	</update>
+	<select id="get" parameterType="string" resultMap="SpecialOpinionMap">
+		select a.*,b.area_id,b.station_name from base_special_opinion a
+		left join base_work_station b on a.work_station_id = b.id_
+		where a.id_=#{0}
+	</select>
+	<select id="exist" parameterType="string" resultType="int">
+		select count(*) from base_special_opinion where id_=#{0}
+	</select>
+	<select id="list" resultMap="SpecialOpinionMap">
+		select * from base_special_opinion
+	</select>
+	<select id="search" parameterType="hashmap" resultMap="SpecialOpinionMap">
+		<![CDATA[
+			select a.*,b.area_id,b.station_name from base_special_opinion a
+			left join base_work_station b on a.work_station_id = b.id_
+			LEFT JOIN base_area c ON b.area_id = c.id_
+		]]>
+		<where>
+			and a.del_flag = 0
+			<if test="searchParams.sort != null">
+				and a.sort_ like #{searchParams.sort}
+			</if>
+			<if test="searchParams.connect != null">
+				and a.connect_ like #{searchParams.connect}
+			</if>
+			<if test="searchParams.connectPhone != null">
+				and a.connect_phone like #{searchParams.connectPhone}
+			</if>
+			<if test="searchParams.areaId != null">
+				and b.area_id = #{searchParams.areaId}
+			</if>
+			<if test="searchParams.code != null">
+				and c.code_ like #{searchParams.code}
+			</if>
+			<if test="searchParams.workStation != null">
+				and a.work_station_id = #{searchParams.workStation}
+			</if>
+			<if test="searchParams.window != null">
+				and a.window_ like #{searchParams.window}
+			</if>
+			<if test="searchParams.isSatisfied != null">
+				and a.is_satisfied = #{searchParams.isSatisfied}
+			</if>
+			<if test="searchParams.opinionStatus != null">
+				and a.opinion_status = #{searchParams.opinionStatus}
+			</if>
+			<if test="searchParams.avail">
+				and a.confirm_status != 2
+			</if>
+			<if test="searchParams.confirmStatus != null">
+				and a.confirm_status = #{searchParams.confirmStatus}
+			</if>
+			<if test="searchParams.cause != null">
+				<foreach collection="searchParams.cause" item="li" open="and (" separator="or" close=")">
+					a.cause_ like #{li}
+				</foreach>
+			</if>
+			<if test="searchParams.reportDateStart != null">
+				<![CDATA[
+				and a.create_time >= #{searchParams.reportDateStart}
+				]]>
+			</if>
+			<if test="searchParams.reportDateEnd != null">
+				<![CDATA[
+				and a.create_time < #{searchParams.reportDateEnd}
+				]]>
+			</if>
+			<if test="searchParams.timeout != null">
+				<![CDATA[
+				and a.alloted_date < #{searchParams.timeout}
+				]]>
+			</if>
+			<if test="searchParams.noTimeout != null">
+				<![CDATA[
+				and (a.alloted_date is null or a.alloted_date >= #{searchParams.noTimeout})
+				]]>
+			</if>
+			<if test="searchParams.year != null">
+				and a.sort_ like #{searchParams.year}
+			</if>
+			<if test="searchParams.lv3 == true">
+				and LENGTH(c.code_) = 110
+				and c.code_ NOT LIKE '%50f3c8f8-5979-470b-9b1d-8c2314ccb2e5%'
+				and c.code_ NOT LIKE '%d452b1d7-3f81-4559-b399-0ae44846fa69%'
+			</if>
+		</where>
+		<foreach item="sort" collection="sortList"  open="order by" separator=",">
+	        ${sort.name} ${sort.order}
+	 	</foreach>
+	</select>
+	<select id="getLastSort" parameterType="string" resultType="string">
+		select sort_ from base_special_opinion
+		where del_flag = 0
+		and sort_ like #{0}
+		order by sort_ desc
+		limit 1
+	</select>
+	<select id="searchTodo" parameterType="hashmap" resultMap="SpecialOpinionMap">
+		<![CDATA[
+			SELECT c.*,a.id_ AS step_status_id,d.station_name FROM base_special_step_status a
+			LEFT JOIN base_special_step b ON a.special_step_id = b.id_
+			LEFT JOIN base_special_opinion c ON b.special_opinion_id = c.id_
+			LEFT JOIN base_work_station d on c.work_station_id = d.id_
+		]]>
+		<where>
+			and c.del_flag = 0
+			and a.status_ = false
+			<if test="searchParams.orgId != null">
+				and a.org_id = #{searchParams.orgId}
+			</if>
+			<if test="searchParams.connectPhone != null">
+				and c.connect_phone like #{searchParams.connectPhone}
+			</if>
+			<if test="searchParams.reportDateStart != null">
+				<![CDATA[
+				and c.create_time >= #{searchParams.reportDateStart}
+				]]>
+			</if>
+			<if test="searchParams.reportDateEnd != null">
+				<![CDATA[
+				and c.create_time < #{searchParams.reportDateEnd}
+				]]>
+			</if>
+		</where>
+		<foreach item="sort" collection="sortList"  open="order by" separator=",">
+			${sort.name} ${sort.order}
+		</foreach>
+	</select>
+</mapper>

+ 91 - 0
common/src/main/resources/mapper/base/SpecialStep.xml

@@ -0,0 +1,91 @@
+<?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">
+<!-- namespace必须指向DAO接口 -->
+<mapper namespace="com.jpsoft.excellent.modules.base.dao.SpecialStepDAO">
+	<resultMap id="SpecialStepMap" type="com.jpsoft.excellent.modules.base.entity.SpecialStep">
+		<id property="id" column="id_" />
+			<result property="specialOpinionId" column="special_opinion_id" />
+			<result property="allotedDate" column="alloted_date" />
+			<result property="delFlag" column="del_flag" />
+			<result property="createTime" column="create_time" />
+			<result property="createBy" column="create_by" />
+			<result property="updateTime" column="update_time" />
+			<result property="updateBy" column="update_by" />
+			</resultMap>
+	<insert id="insert" parameterType="com.jpsoft.excellent.modules.base.entity.SpecialStep">
+	<!--
+	<selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id">
+		select sys_guid() from dual
+	</selectKey>
+	-->
+	<![CDATA[
+		insert into base_special_step
+	    (id_,special_opinion_id,alloted_date,del_flag,create_time,create_by,update_time,update_by)
+		values
+		(
+#{id,jdbcType=VARCHAR}
+,#{specialOpinionId,jdbcType=VARCHAR}
+,#{allotedDate,jdbcType= TIMESTAMP }
+,#{delFlag,jdbcType= NUMERIC }
+,#{createTime,jdbcType= TIMESTAMP }
+,#{createBy,jdbcType=VARCHAR}
+,#{updateTime,jdbcType= TIMESTAMP }
+,#{updateBy,jdbcType=VARCHAR}
+		)
+	]]>
+	</insert>
+	<delete id="delete" parameterType="string">
+		delete from base_special_step where id_=#{id,jdbcType=VARCHAR}
+	</delete>
+	<update id="update" parameterType="com.jpsoft.excellent.modules.base.entity.SpecialStep">
+		update base_special_step
+		<set>
+				<if test="specialOpinionId!=null">
+		special_opinion_id=#{specialOpinionId,jdbcType=VARCHAR},
+		</if>
+				<if test="allotedDate!=null">
+		alloted_date=#{allotedDate,jdbcType= TIMESTAMP },
+		</if>
+				<if test="delFlag!=null">
+		del_flag=#{delFlag,jdbcType= NUMERIC },
+		</if>
+				<if test="createTime!=null">
+		create_time=#{createTime,jdbcType= TIMESTAMP },
+		</if>
+				<if test="createBy!=null">
+		create_by=#{createBy,jdbcType=VARCHAR},
+		</if>
+				<if test="updateTime!=null">
+		update_time=#{updateTime,jdbcType= TIMESTAMP },
+		</if>
+				<if test="updateBy!=null">
+		update_by=#{updateBy,jdbcType=VARCHAR},
+		</if>
+		</set>
+	where id_=#{id}
+	</update>
+	<select id="get" parameterType="string" resultMap="SpecialStepMap">
+		select 
+id_,special_opinion_id,alloted_date,del_flag,create_time,create_by,update_time,update_by		from base_special_step where id_=#{0}
+	</select>
+	<select id="exist" parameterType="string" resultType="int">
+		select count(*) from base_special_step where id_=#{0}
+	</select>
+	<select id="list" resultMap="SpecialStepMap">
+		select * from base_special_step
+	</select>
+	<select id="search" parameterType="hashmap" resultMap="SpecialStepMap">
+		<![CDATA[
+			select * from base_special_step
+		]]>
+		<where>
+			<if test="searchParams.id != null">
+				and ID_ like #{searchParams.id}
+			</if>
+		</where>
+		<foreach item="sort" collection="sortList"  open="order by" separator=",">
+	        ${sort.name} ${sort.order}
+	 	</foreach>
+	</select>
+</mapper>

+ 127 - 0
common/src/main/resources/mapper/base/SpecialStepStatus.xml

@@ -0,0 +1,127 @@
+<?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">
+<!-- namespace必须指向DAO接口 -->
+<mapper namespace="com.jpsoft.excellent.modules.base.dao.SpecialStepStatusDAO">
+	<resultMap id="SpecialStepStatusMap" type="com.jpsoft.excellent.modules.base.entity.SpecialStepStatus">
+		<id property="id" column="id_" />
+			<result property="specialStepId" column="special_step_id" />
+			<result property="orgId" column="org_id" />
+			<result property="userId" column="user_id" />
+			<result property="content" column="content_" />
+			<result property="status" column="status_" />
+			<result property="allotedDate" column="alloted_date" />
+			<result property="delFlag" column="del_flag" />
+			<result property="createTime" column="create_time" />
+			<result property="createBy" column="create_by" />
+			<result property="updateTime" column="update_time" />
+			<result property="updateBy" column="update_by" />
+			</resultMap>
+	<insert id="insert" parameterType="com.jpsoft.excellent.modules.base.entity.SpecialStepStatus">
+	<!--
+	<selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id">
+		select sys_guid() from dual
+	</selectKey>
+	-->
+	<![CDATA[
+		insert into base_special_step_status
+	    (id_,special_step_id,org_id,user_id,content_,status_,alloted_date,del_flag,create_time,create_by,update_time,update_by)
+		values
+		(
+#{id,jdbcType=VARCHAR}
+,#{specialStepId,jdbcType=VARCHAR}
+,#{orgId,jdbcType=VARCHAR}
+,#{userId,jdbcType=VARCHAR}
+,#{content,jdbcType=VARCHAR}
+,#{status,jdbcType= NUMERIC }
+,#{allotedDate,jdbcType= TIMESTAMP }
+,#{delFlag,jdbcType= NUMERIC }
+,#{createTime,jdbcType= TIMESTAMP }
+,#{createBy,jdbcType=VARCHAR}
+,#{updateTime,jdbcType= TIMESTAMP }
+,#{updateBy,jdbcType=VARCHAR}
+		)
+	]]>
+	</insert>
+	<delete id="delete" parameterType="string">
+		delete from base_special_step_status where id_=#{id,jdbcType=VARCHAR}
+	</delete>
+	<update id="update" parameterType="com.jpsoft.excellent.modules.base.entity.SpecialStepStatus">
+		update base_special_step_status
+		<set>
+				<if test="specialStepId!=null">
+		special_step_id=#{specialStepId,jdbcType=VARCHAR},
+		</if>
+				<if test="orgId!=null">
+					org_id=#{orgId,jdbcType=VARCHAR},
+		</if>
+				<if test="userId!=null">
+		user_id=#{userId,jdbcType=VARCHAR},
+		</if>
+				<if test="content!=null">
+		content_=#{content,jdbcType=VARCHAR},
+		</if>
+				<if test="status!=null">
+		status_=#{status,jdbcType= NUMERIC },
+		</if>
+				<if test="allotedDate!=null">
+		alloted_date=#{allotedDate,jdbcType= TIMESTAMP },
+		</if>
+				<if test="delFlag!=null">
+		del_flag=#{delFlag,jdbcType= NUMERIC },
+		</if>
+				<if test="createTime!=null">
+		create_time=#{createTime,jdbcType= TIMESTAMP },
+		</if>
+				<if test="createBy!=null">
+		create_by=#{createBy,jdbcType=VARCHAR},
+		</if>
+				<if test="updateTime!=null">
+		update_time=#{updateTime,jdbcType= TIMESTAMP },
+		</if>
+				<if test="updateBy!=null">
+		update_by=#{updateBy,jdbcType=VARCHAR},
+		</if>
+		</set>
+	where id_=#{id}
+	</update>
+	<select id="get" parameterType="string" resultMap="SpecialStepStatusMap">
+		select 
+id_,special_step_id,org_id,user_id,content_,status_,alloted_date,del_flag,create_time,create_by,update_time,update_by		from base_special_step_status where id_=#{0}
+	</select>
+	<select id="exist" parameterType="string" resultType="int">
+		select count(*) from base_special_step_status where id_=#{0}
+	</select>
+	<select id="list" resultMap="SpecialStepStatusMap">
+		select * from base_special_step_status
+	</select>
+	<select id="search" parameterType="hashmap" resultMap="SpecialStepStatusMap">
+		<![CDATA[
+			select * from base_special_step_status
+		]]>
+		<where>
+			<if test="searchParams.id != null">
+				and ID_ like #{searchParams.id}
+			</if>
+		</where>
+		<foreach item="sort" collection="sortList"  open="order by" separator=",">
+	        ${sort.name} ${sort.order}
+	 	</foreach>
+	</select>
+	<select id="findByList" resultMap="SpecialStepStatusMap">
+		SELECT a.* FROM base_special_step_status a
+		LEFT JOIN base_special_step b ON a.special_step_id = b.id_
+		WHERE b.special_opinion_id = #{specialOpinionId}
+		<if test="status != null">
+			AND a.status_ = #{status}
+		</if>
+		ORDER BY create_time ASC
+	</select>
+	<select id="findPhoneByRemind" resultType="string">
+		SELECT b.phone_ FROM base_special_step_status a
+		LEFT JOIN sys_user b ON a.org_id = b.org_id
+		WHERE a.status_ = FALSE
+		AND a.create_time LIKE #{0}
+		GROUP BY b.phone_
+	</select>
+</mapper>

+ 1144 - 0
web/src/main/java/com/jpsoft/excellent/modules/base/controller/SpecialOpinionController.java

@@ -0,0 +1,1144 @@
+package com.jpsoft.excellent.modules.base.controller;
+
+import com.github.pagehelper.Page;
+import com.jpsoft.excellent.config.OSSConfig;
+import com.jpsoft.excellent.modules.base.dto.AttachmentDTO;
+import com.jpsoft.excellent.modules.base.dto.SpecialOpinionReportDTO;
+import com.jpsoft.excellent.modules.base.dto.NextStepDTO;
+import com.jpsoft.excellent.modules.base.entity.*;
+import com.jpsoft.excellent.modules.base.service.*;
+import com.jpsoft.excellent.modules.common.dto.MessageResult;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+import com.jpsoft.excellent.modules.common.utils.OSSUtil;
+import com.jpsoft.excellent.modules.common.utils.PojoUtils;
+import com.jpsoft.excellent.modules.common.utils.SMSUtil;
+import com.jpsoft.excellent.modules.sys.entity.User;
+import com.jpsoft.excellent.modules.sys.service.DataDictionaryService;
+import com.jpsoft.excellent.modules.sys.service.UserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@RestController
+@RequestMapping("/base/specialOpinion")
+@Api(description = "specialOpinion")
+public class SpecialOpinionController {
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Autowired
+    private OSSConfig ossConfig;
+    @Autowired
+    private DataDictionaryService dataDictionaryService;
+    @Autowired
+    private UserService userService;
+    @Autowired
+    private WorkStationService workStationService;
+    @Autowired
+    private SpecialOpinionService specialOpinionService;
+    @Autowired
+    private SpecialStepService specialStepService;
+    @Autowired
+    private SpecialStepStatusService specialStepStatusService;
+    @Autowired
+    private SpecialAttachmentService specialAttachmentService;
+    @Autowired
+    private AreaService areaService;
+    @Autowired
+    private OrganizationService organizationService;
+
+    @ApiOperation(value="创建空记录")
+    @GetMapping("create")
+    public MessageResult<SpecialOpinion> create(){
+        MessageResult<SpecialOpinion> msgResult = new MessageResult<>();
+
+        List<AttachmentDTO> specialAttachmentList = new ArrayList<AttachmentDTO>();
+
+        SpecialOpinion specialOpinion = new SpecialOpinion();
+        specialOpinion.setAttList(specialAttachmentList);
+        specialOpinion.setPicList(specialAttachmentList);
+
+        msgResult.setData(specialOpinion);
+        msgResult.setResult(true);
+
+        return msgResult;
+    }
+    
+    @ApiOperation(value="添加信息")
+    @PostMapping("add")
+    public MessageResult<SpecialOpinion> add(@RequestBody SpecialOpinion specialOpinion,@RequestAttribute String subject){
+        MessageResult<SpecialOpinion> msgResult = new MessageResult<>();
+
+        try {
+            specialOpinion.setId(UUID.randomUUID().toString());
+            specialOpinion.setDelFlag(false);
+            specialOpinion.setCreateBy(subject);
+            specialOpinion.setCreateTime(new Date());
+            
+            int affectCount = specialOpinionService.insert(specialOpinion);
+
+            if (affectCount > 0) {
+                msgResult.setResult(true);
+                msgResult.setData(specialOpinion);
+            } else {
+                msgResult.setResult(false);
+                msgResult.setMessage("数据库添加失败");
+            }
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+
+    @ApiOperation(value="获取信息")
+    @GetMapping("edit/{id}")
+    public MessageResult<SpecialOpinion> edit(@PathVariable("id") String id, @RequestAttribute String subject){
+        MessageResult<SpecialOpinion> msgResult = new MessageResult<>();
+
+        try {
+            User userNow = userService.get(subject);
+            SpecialOpinion specialOpinion = specialOpinionService.get(id);
+            specialOpinion.setUpdateBy(userNow.getStationId());
+            Area area = areaService.get(specialOpinion.getAreaId());
+            if(area != null){
+                specialOpinion.setAreaName(area.getName());
+            }
+            if(StringUtils.isNotEmpty(specialOpinion.getAppendix())){
+                specialOpinion.setAppendixList(specialOpinion.getAppendix().split(","));
+            }
+
+            //附件列表
+            List<AttachmentDTO> attachmentDTOList1 = new ArrayList<>();
+            List<SpecialAttachment> specialAttachmentList1 = specialAttachmentService.findListBySpecialOpinionId(id,"3");
+            for(SpecialAttachment specialAttachment : specialAttachmentList1){
+                AttachmentDTO attachmentDTO = new AttachmentDTO();
+                attachmentDTO.setName(specialAttachment.getAttachmentTitle());
+                attachmentDTO.setUrl(specialAttachment.getAttachmentUrl());
+                attachmentDTOList1.add(attachmentDTO);
+            }
+            specialOpinion.setAttList(attachmentDTOList1);
+            //图片列表
+            List<AttachmentDTO> attachmentDTOList2 = new ArrayList<>();
+            List<SpecialAttachment> specialAttachmentList2 = specialAttachmentService.findListBySpecialOpinionId(id,"2");
+            String[] picUrlList = new String[specialAttachmentList2.size()];
+            for(int i=0;i<specialAttachmentList2.size();i++){
+                SpecialAttachment specialAttachment = specialAttachmentList2.get(i);
+                AttachmentDTO attachmentDTO = new AttachmentDTO();
+                attachmentDTO.setName(specialAttachment.getAttachmentTitle());
+                attachmentDTO.setUrl(specialAttachment.getAttachmentUrl());
+                attachmentDTOList2.add(attachmentDTO);
+                picUrlList[i] = specialAttachment.getAttachmentUrl();
+            }
+            specialOpinion.setPicList(attachmentDTOList2);
+            specialOpinion.setPicUrlList(picUrlList);
+            //步进列表
+            List<SpecialStepStatus> specialStepStatusList = specialStepStatusService.findByList(specialOpinion.getId(),null);
+            for(SpecialStepStatus specialStepStatus : specialStepStatusList){
+                if(StringUtils.isNotEmpty(specialStepStatus.getOrgId())){
+                    Organization organization = organizationService.get(specialStepStatus.getOrgId());
+                    specialStepStatus.setOrgName(organization.getName());
+                }
+                if(StringUtils.isNotEmpty(specialStepStatus.getUserId())){
+                    User user = userService.get(specialStepStatus.getUserId());
+                    specialStepStatus.setUserName(user.getRealName());
+                }
+            }
+            specialOpinion.setStepStatusList(specialStepStatusList);
+            
+            if (specialOpinion != null) {
+                msgResult.setResult(true);
+                msgResult.setData(specialOpinion);
+            } else {
+                msgResult.setResult(false);
+                msgResult.setMessage("数据库不存在该记录!");
+            }
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+
+    @ApiOperation(value="更新用户")
+    @PostMapping("update")
+    public MessageResult<SpecialOpinion> update(@RequestBody SpecialOpinion specialOpinion,@RequestAttribute String subject){
+        MessageResult<SpecialOpinion> msgResult = new MessageResult<>();
+
+        try {
+            specialOpinion.setUpdateBy(subject);
+            specialOpinion.setUpdateTime(new Date());
+            
+            int affectCount = specialOpinionService.update(specialOpinion);
+
+            if (affectCount > 0) {
+                if (specialOpinion.getConfirmStatus() == null || specialOpinion.getConfirmStatus() == 0) {
+                    //删除关联附件及图片
+                    List<SpecialAttachment> specialAttachmentList = specialAttachmentService.findListBySpecialOpinionId(specialOpinion.getId(), null);
+                    for (SpecialAttachment specialAttachment : specialAttachmentList) {
+                        specialAttachmentService.delete(specialAttachment.getId());
+                    }
+                    //关联附件
+                    for (int i = 0; i < specialOpinion.getAttList().size(); i++) {
+                        AttachmentDTO attachmentDTO = specialOpinion.getAttList().get(i);
+                        SpecialAttachment specialAttachment = new SpecialAttachment();
+                        specialAttachment.setId(UUID.randomUUID().toString());
+                        specialAttachment.setSpecialOpinionId(specialOpinion.getId());
+                        specialAttachment.setAttachmentType("1");
+                        specialAttachment.setAttachmentTitle(attachmentDTO.getName());
+                        specialAttachment.setAttachmentUrl(attachmentDTO.getUrl());
+                        specialAttachment.setSortNo(i);
+                        specialAttachment.setCreateBy(subject);
+                        specialAttachment.setCreateTime(new Date());
+                        specialAttachmentService.insert(specialAttachment);
+                    }
+                    //关联图片
+                    for (int i = 0; i < specialOpinion.getPicList().size(); i++) {
+                        AttachmentDTO attachmentDTO = specialOpinion.getPicList().get(i);
+                        SpecialAttachment specialAttachment = new SpecialAttachment();
+                        specialAttachment.setId(UUID.randomUUID().toString());
+                        specialAttachment.setSpecialOpinionId(specialOpinion.getId());
+                        specialAttachment.setAttachmentType("2");
+                        specialAttachment.setAttachmentTitle(attachmentDTO.getName());
+                        specialAttachment.setAttachmentUrl(attachmentDTO.getUrl());
+                        specialAttachment.setSortNo(i);
+                        specialAttachment.setCreateBy(subject);
+                        specialAttachment.setCreateTime(new Date());
+                        specialAttachmentService.insert(specialAttachment);
+                    }
+                }
+
+                msgResult.setResult(true);
+                msgResult.setData(specialOpinion);
+            } else {
+                msgResult.setResult(false);
+                msgResult.setMessage("数据库更新失败");
+            }
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+
+    @ApiOperation(value="删除")
+    @PostMapping("delete/{id}")
+    public MessageResult<Integer> delete(@PathVariable("id") String id,@RequestAttribute String subject){
+        MessageResult<Integer> msgResult = new MessageResult<>();
+
+        try {
+            SpecialOpinion specialOpinion = specialOpinionService.get(id);
+            specialOpinion.setDelFlag(true);
+            specialOpinion.setUpdateBy(subject);
+            specialOpinion.setUpdateTime(new Date());
+
+            int affectCount = specialOpinionService.update(specialOpinion);
+
+            if (affectCount > 0) {
+                msgResult.setResult(true);
+                msgResult.setData(affectCount);
+            } else {
+                msgResult.setResult(false);
+                msgResult.setMessage("删除失败");
+            }
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+
+
+    @ApiOperation(value="批量删除")
+    @PostMapping("batchDelete")
+    public MessageResult<Integer> batchDelete(@RequestBody List<String> idList,@RequestAttribute String subject){
+        MessageResult<Integer> msgResult = new MessageResult<>();
+
+        try {
+            int affectCount = 0;
+
+            for (String id : idList) {
+                SpecialOpinion specialOpinion = specialOpinionService.get(id);
+                specialOpinion.setDelFlag(true);
+                specialOpinion.setUpdateBy(subject);
+                specialOpinion.setUpdateTime(new Date());
+
+                affectCount += specialOpinionService.update(specialOpinion);
+            }
+
+            if (affectCount > 0) {
+                msgResult.setResult(true);
+                msgResult.setData(affectCount);
+            } else {
+                msgResult.setResult(false);
+                msgResult.setMessage("删除失败");
+            }
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+
+    @ApiOperation(value="列表")
+    @RequestMapping(value = "pageList",method = RequestMethod.POST)
+    public MessageResult<Map> pageList(
+            String sort, String connect, String connectPhone, String areaId, String workStation, String window,
+            String isSatisfied, String opinionStatus, String confirmStatus, Date[] reportDate,
+            Boolean areaSubordinate, String timeout,
+            @RequestParam(value="pageIndex",defaultValue="1") int pageIndex,
+            @RequestParam(value="pageSize",defaultValue="20") int pageSize,
+            @RequestAttribute String subject){
+        MessageResult<Map> msgResult = new MessageResult<>();
+
+        Map<String,Object> searchParams = new HashMap<>();
+
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("create_time","desc"));
+
+        if (StringUtils.isNotEmpty(sort)) {
+            searchParams.put("sort","%" + sort + "%");
+        }
+        if (StringUtils.isNotEmpty(connect)) {
+            searchParams.put("connect","%" + connect + "%");
+        }
+        if (StringUtils.isNotEmpty(connectPhone)) {
+            searchParams.put("connectPhone","%" + connectPhone + "%");
+        }
+        if (StringUtils.isNotEmpty(areaId) && !"null".equals(areaId)) {
+            if (areaSubordinate) {
+                Area area = areaService.get(areaId);
+                searchParams.put("code", area.getCode() + "%");
+            }
+            else {
+                searchParams.put("areaId", areaId);
+            }
+        }
+
+        if (StringUtils.isNotEmpty(workStation)) {
+            searchParams.put("workStation",workStation);
+        }
+        if (StringUtils.isNotEmpty(window)) {
+            searchParams.put("window","%"+window+"%");
+        }
+        if (StringUtils.isNotEmpty(isSatisfied)) {
+            if("1".equals(isSatisfied)) {
+                searchParams.put("isSatisfied", true);
+            }
+            if("0".equals(isSatisfied)) {
+                searchParams.put("isSatisfied", false);
+            }
+        }
+        if (StringUtils.isNotEmpty(opinionStatus)) {
+            if("1".equals(opinionStatus)) {
+                searchParams.put("opinionStatus", true);
+            }
+            if("0".equals(opinionStatus)) {
+                searchParams.put("opinionStatus", false);
+            }
+        }
+        if (StringUtils.isNotEmpty(confirmStatus)) {
+            searchParams.put("confirmStatus", confirmStatus);
+        }
+        else {
+            searchParams.put("avail", true);
+        }
+        if (StringUtils.isNotEmpty(timeout)) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            if("1".equals(timeout)) {
+                searchParams.put("timeout", sdf.format(new Date()));
+            }
+            if("0".equals(timeout)) {
+                searchParams.put("noTimeout", sdf.format(new Date()));
+            }
+        }
+        if (reportDate.length > 0) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            Calendar calendar = new GregorianCalendar();
+            calendar.setTime(reportDate[1]);
+            calendar.add(calendar.DATE,1);
+
+            searchParams.put("reportDateStart",sdf.format(reportDate[0]));
+            searchParams.put("reportDateEnd",sdf.format(calendar.getTime()));
+        }
+
+        Page<SpecialOpinion> page = specialOpinionService.pageSearch(searchParams,pageIndex,pageSize,true,sortList);
+        for(SpecialOpinion specialOpinion : page.getResult()){
+            if(StringUtils.isNotEmpty(specialOpinion.getAreaId())) {
+                specialOpinion.setAreaName(parentFullName(specialOpinion.getAreaId()));
+            }
+            int num = specialStepStatusService.findByList(specialOpinion.getId(),false).size();
+            if(num > 0) {
+                specialOpinion.setIsProcessed(false);
+            }
+            else{
+                specialOpinion.setIsProcessed(true);
+            }
+        }
+
+        msgResult.setResult(true);
+        msgResult.setData(PojoUtils.pageWrapper(page));
+
+        return msgResult;
+    }
+
+    @ApiOperation(value="导出报表")
+    @RequestMapping(value = "reportListXls",method = RequestMethod.POST)
+    public String reportListXls(String sort, String connect, String connectPhone, String areaId, String workStation, String window,
+                                String isSatisfied, String opinionStatus, String confirmStatus, Date[] reportDate,
+                                Boolean areaSubordinate, String timeout, @RequestAttribute String subject){
+        String downloadUrl = "";
+
+        //新建文档
+        Workbook workbook = new HSSFWorkbook();
+        Sheet sheet = workbook.createSheet();
+
+        //单元格样式
+        sheet.setDefaultColumnWidth(15);
+        sheet.setDefaultRowHeight((short) 400);
+
+        Font fontTitle = workbook.createFont();
+        fontTitle.setFontName("宋体");
+        fontTitle.setFontHeightInPoints((short) 11);
+        fontTitle.setBold(true);
+
+        CellStyle cellStyleTitle = workbook.createCellStyle();
+        cellStyleTitle.setBorderTop(BorderStyle.THIN);
+        cellStyleTitle.setBorderBottom(BorderStyle.THIN);
+        cellStyleTitle.setBorderLeft(BorderStyle.THIN);
+        cellStyleTitle.setBorderRight(BorderStyle.THIN);
+        cellStyleTitle.setVerticalAlignment(VerticalAlignment.CENTER);
+        cellStyleTitle.setAlignment(HorizontalAlignment.CENTER);
+        cellStyleTitle.setFont(fontTitle);
+
+        Font fontContent = workbook.createFont();
+        fontContent.setFontName("宋体");
+        fontContent.setFontHeightInPoints((short) 11);
+
+        CellStyle cellStyleContent = workbook.createCellStyle();
+        cellStyleContent.setBorderTop(BorderStyle.THIN);
+        cellStyleContent.setBorderBottom(BorderStyle.THIN);
+        cellStyleContent.setBorderLeft(BorderStyle.THIN);
+        cellStyleContent.setBorderRight(BorderStyle.THIN);
+        cellStyleContent.setVerticalAlignment(VerticalAlignment.CENTER);
+        cellStyleContent.setAlignment(HorizontalAlignment.CENTER);
+        cellStyleContent.setFont(fontContent);
+
+        //表头
+        Row rowTitle = sheet.createRow(0);
+        String[] titles = new String[]{"序号","联系人","联系电话","区域","站点","窗口","是否满意","内容","上报时间","处理进度","确认状态"};
+        for (int i=0;i<titles.length;i++) {
+            Cell cell = rowTitle.createCell(i);
+            cell.setCellValue(titles[i]);
+            cell.setCellStyle(cellStyleTitle);
+        }
+
+        //读取数据
+        Map<String,Object> searchParams = new HashMap<>();
+
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("create_time","asc"));
+
+        if (StringUtils.isNotEmpty(sort)) {
+            searchParams.put("sort","%" + sort + "%");
+        }
+        if (StringUtils.isNotEmpty(connect)) {
+            searchParams.put("connect","%" + connect + "%");
+        }
+        if (StringUtils.isNotEmpty(connectPhone)) {
+            searchParams.put("connectPhone","%" + connectPhone + "%");
+        }
+        if (StringUtils.isNotEmpty(areaId) && !"null".equals(areaId)) {
+            if (areaSubordinate) {
+                Area area = areaService.get(areaId);
+                searchParams.put("code", area.getCode() + "%");
+            }
+            else {
+                searchParams.put("areaId", areaId);
+            }
+        }
+        if (StringUtils.isNotEmpty(workStation)) {
+            searchParams.put("workStation",workStation);
+        }
+        if (StringUtils.isNotEmpty(window)) {
+            searchParams.put("window","%"+window+"%");
+        }
+        if (StringUtils.isNotEmpty(isSatisfied)) {
+            if("1".equals(isSatisfied)) {
+                searchParams.put("isSatisfied", true);
+            }
+            if("0".equals(isSatisfied)) {
+                searchParams.put("isSatisfied", false);
+            }
+        }
+        if (StringUtils.isNotEmpty(opinionStatus)) {
+            if("1".equals(opinionStatus)) {
+                searchParams.put("opinionStatus", true);
+            }
+            if("0".equals(opinionStatus)) {
+                searchParams.put("opinionStatus", false);
+            }
+        }
+        if (StringUtils.isNotEmpty(confirmStatus)) {
+            searchParams.put("confirmStatus", confirmStatus);
+        }
+        if (StringUtils.isNotEmpty(timeout)) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            if("1".equals(timeout)) {
+                searchParams.put("timeout", sdf.format(new Date()));
+            }
+            if("0".equals(timeout)) {
+                searchParams.put("noTimeout", sdf.format(new Date()));
+            }
+        }
+        if (reportDate.length > 0) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            Calendar calendar = new GregorianCalendar();
+            calendar.setTime(reportDate[1]);
+            calendar.add(calendar.DATE,1);
+
+            searchParams.put("reportDateStart",sdf.format(reportDate[0]));
+            searchParams.put("reportDateEnd",sdf.format(calendar.getTime()));
+        }
+
+        Page<SpecialOpinion> page = specialOpinionService.pageSearch(searchParams,1,100000,false,sortList);
+        //写入数据
+        for(int i=0; i<page.getResult().size(); i++){
+            SpecialOpinion specialOpinion = page.getResult().get(i);
+
+            Row row = sheet.createRow(i+1);
+            row.createCell(0);
+            row.createCell(1);
+            row.createCell(2);
+            row.createCell(3);
+            row.createCell(4);
+            row.createCell(5);
+            row.createCell(6);
+            row.createCell(7);
+            row.createCell(8);
+            row.createCell(9);
+            row.createCell(10);
+
+            row.getCell(0).setCellValue(specialOpinion.getSort());
+            row.getCell(1).setCellValue(specialOpinion.getConnect());
+            row.getCell(2).setCellValue(specialOpinion.getConnectPhone());
+            row.getCell(3).setCellValue(parentFullName(specialOpinion.getAreaId()));
+            row.getCell(4).setCellValue(specialOpinion.getStationName());
+            row.getCell(5).setCellValue(specialOpinion.getWindow());
+            if(specialOpinion.getIsSatisfied()){
+                row.getCell(6).setCellValue("满意");
+            }
+            else{
+                row.getCell(6).setCellValue("不满意");
+            }
+            row.getCell(7).setCellValue(specialOpinion.getContent());
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            row.getCell(8).setCellValue(sdf.format(specialOpinion.getCreateTime()));
+            if(specialOpinion.getOpinionStatus()){
+                row.getCell(9).setCellValue("已处理");
+            }
+            else{
+                row.getCell(9).setCellValue("未处理");
+            }
+            if(specialOpinion.getConfirmStatus() == 1){
+                row.getCell(10).setCellValue("已确认");
+            }
+            if(specialOpinion.getConfirmStatus() == 0){
+                row.getCell(10).setCellValue("待确认");
+            }
+            if(specialOpinion.getConfirmStatus() == 2){
+                row.getCell(10).setCellValue("忽略");
+            }
+
+            row.getCell(0).setCellStyle(cellStyleContent);
+            row.getCell(1).setCellStyle(cellStyleContent);
+            row.getCell(2).setCellStyle(cellStyleContent);
+            row.getCell(3).setCellStyle(cellStyleContent);
+            row.getCell(4).setCellStyle(cellStyleContent);
+            row.getCell(5).setCellStyle(cellStyleContent);
+            row.getCell(6).setCellStyle(cellStyleContent);
+            row.getCell(7).setCellStyle(cellStyleContent);
+            row.getCell(8).setCellStyle(cellStyleContent);
+            row.getCell(9).setCellStyle(cellStyleContent);
+            row.getCell(10).setCellStyle(cellStyleContent);
+        }
+
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        try {
+            workbook.write(output);
+
+            byte[] buffer = output.toByteArray();
+            ByteArrayInputStream input = new ByteArrayInputStream(buffer);
+
+            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmm");
+            String now = sdf2.format(new Date());
+            String fileName = "反馈意见-" + now + ".xls";
+            downloadUrl = OSSUtil.upload(ossConfig,"InsuranceReport",fileName,input);
+        }
+        catch (Exception ex){
+            logger.error(ex.getMessage(),ex);
+        }
+
+        return downloadUrl;
+    }
+
+    @ApiOperation(value="导出上报报表")
+    @RequestMapping(value = "reportListXlsSB",method = RequestMethod.POST)
+    public String reportListXlsSB(Date[] reportDate, @RequestAttribute String subject){
+        String downloadUrl = "";
+
+        try{
+            String xlsPath = "static/jzs_qzp_pjsjb.xls";
+            ClassPathResource resource = new ClassPathResource(xlsPath);
+            Workbook workbook = WorkbookFactory.create(resource.getInputStream());
+            Sheet sheet = workbook.getSheetAt(0);
+
+            //读取数据
+            Map<String,Object> searchParams = new HashMap<>();
+            searchParams.put("lv3",true);
+            if (reportDate.length > 0) {
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+                Calendar calendar = new GregorianCalendar();
+                calendar.setTime(reportDate[1]);
+                calendar.add(calendar.DATE,1);
+
+                searchParams.put("reportDateStart",sdf.format(reportDate[0]));
+                searchParams.put("reportDateEnd",sdf.format(calendar.getTime()));
+            }
+
+            List<Sort> sortList = new ArrayList<>();
+            sortList.add(new Sort("create_time","asc"));
+
+            Page<SpecialOpinion> page = specialOpinionService.pageSearch(searchParams,1,100000,false,sortList);
+
+            //写入数据
+            for(int i=0; i<page.getResult().size(); i++){
+                SpecialOpinion specialOpinion = page.getResult().get(i);
+
+                Row row = sheet.createRow(i+2);
+                row.createCell(0).setCellValue(specialOpinion.getId());
+//                row.createCell(1).setCellValue(1);
+                if(StringUtils.isNotEmpty(specialOpinion.getAreaId())) {
+                    Area area = areaService.get(specialOpinion.getAreaId());
+                    row.createCell(2).setCellValue(area.getName());
+                }
+                row.createCell(3).setCellValue("5");
+//                row.createCell(4).setCellValue(4);
+                row.createCell(5).setCellValue(specialOpinion.getStationName());
+                row.createCell(6).setCellValue(specialOpinion.getConnect());
+                row.createCell(7).setCellValue(specialOpinion.getConnectPhone());
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                row.createCell(8).setCellValue(sdf.format(specialOpinion.getCreateTime()));
+                if(specialOpinion.getIsSatisfied()){
+                    row.createCell(9).setCellValue("4");
+                }
+                else{
+                    row.createCell(9).setCellValue("2");
+                }
+//                row.createCell(10).setCellValue(10);
+//                row.createCell(11).setCellValue(11);
+//                row.createCell(12).setCellValue(12);
+//                row.createCell(13).setCellValue(13);
+                row.createCell(14).setCellValue(specialOpinion.getContent());
+                if(specialOpinion.getConfirmStatus() == 2){
+                    row.createCell(15).setCellValue("0");
+                }
+                else{
+                    row.createCell(15).setCellValue("1");
+                }
+                if(specialOpinion.getOpinionStatus()){
+                    row.createCell(16).setCellValue("1");
+                }
+                else{
+                    row.createCell(16).setCellValue("0");
+                }
+//                row.createCell(17).setCellValue(17);
+                if(StringUtils.isNotEmpty(specialOpinion.getContentAttachment())) {
+                    row.createCell(18).setCellValue(specialOpinion.getContentAttachment());
+                }
+                if(specialOpinion.getUpdateTime() != null) {
+                    row.createCell(19).setCellValue(sdf.format(specialOpinion.getUpdateTime()));
+                    row.createCell(20).setCellValue(sdf.format(specialOpinion.getUpdateTime()));
+                }
+                row.createCell(21).setCellValue("I");
+            }
+
+            ByteArrayOutputStream output = new ByteArrayOutputStream();
+            workbook.write(output);
+            byte[] buffer = output.toByteArray();
+            ByteArrayInputStream input = new ByteArrayInputStream(buffer);
+
+            String fileName = "荆州市双优督办反馈报表.xls";
+            downloadUrl = OSSUtil.upload(ossConfig,"InsuranceReport",fileName,input);
+        }
+        catch (Exception ex){
+            logger.error(ex.getMessage(),ex);
+        }
+
+        return downloadUrl;
+    }
+
+    @ApiOperation(value="列表")
+    @RequestMapping(value = "pageListStatistics",method = RequestMethod.POST)
+    public MessageResult<List> pageListStatistics(String areaId, String workStation, String isSatisfied, Date[] reportDate){
+        MessageResult<List> msgResult = new MessageResult<>();
+        List<SpecialOpinionReportDTO> list = new ArrayList<>();
+
+        if(StringUtils.isNotEmpty(areaId)) {
+            Map<String, Object> searchParams = new HashMap<>();
+//        if (StringUtils.isNotEmpty(workStation)) {
+//            searchParams.put("workStation", workStation);
+//        }
+//        if (StringUtils.isNotEmpty(isSatisfied)) {
+//            if ("1".equals(isSatisfied)) {
+//                searchParams.put("isSatisfied", true);
+//            }
+//            if ("0".equals(isSatisfied)) {
+//                searchParams.put("isSatisfied", false);
+//            }
+//        }
+            if (reportDate.length > 0) {
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+                Calendar calendar = new GregorianCalendar();
+                calendar.setTime(reportDate[1]);
+                calendar.add(calendar.DATE, 1);
+
+                searchParams.put("reportDateStart", sdf.format(reportDate[0]));
+                searchParams.put("reportDateEnd", sdf.format(calendar.getTime()));
+            }
+
+            List<Sort> sortList = new ArrayList<>();
+            sortList.add(new Sort("create_time", "desc"));
+
+            //区域-直属
+            Integer ZsMY = 0;
+            Integer ZsBMY = 0;
+            Integer ZsYCL = 0;
+            Integer ZsWCY = 0;
+            Integer ZsYQR = 0;
+            Integer ZsWQR = 0;
+            Area areaZS = areaService.get(areaId);
+            searchParams.put("areaId", areaId);
+            Page<SpecialOpinion> pageZS = specialOpinionService.pageSearch(searchParams, 1, 10000, false, sortList);
+            for (SpecialOpinion specialOpinion : pageZS.getResult()) {
+                if (specialOpinion.getIsSatisfied() != null && specialOpinion.getIsSatisfied()) {
+                    ZsMY++;
+                } else {
+                    ZsBMY++;
+                }
+                if (specialOpinion.getOpinionStatus() != null && specialOpinion.getOpinionStatus()) {
+                    ZsYCL++;
+                } else {
+                    ZsWCY++;
+                }
+                if (specialOpinion.getConfirmStatus() != null && specialOpinion.getConfirmStatus() == 1) {
+                    ZsYQR++;
+                } else {
+                    ZsWQR++;
+                }
+            }
+
+            SpecialOpinionReportDTO ZsDto = new SpecialOpinionReportDTO();
+            ZsDto.setArea(areaZS.getName()+"直属");
+            ZsDto.setCountMY(ZsMY);
+            ZsDto.setCountBMY(ZsBMY);
+            ZsDto.setCountYCL(ZsYCL);
+            ZsDto.setCountWCL(ZsWCY);
+            ZsDto.setCountYQR(ZsYQR);
+            ZsDto.setCountWQR(ZsWQR);
+            list.add(ZsDto);
+
+            searchParams.remove("areaId");
+
+            //区域-下级
+            List<Area> areaList = areaService.getListByParentId(areaId);
+            for (Area area : areaList) {
+                Integer countMY = 0;
+                Integer countBMY = 0;
+                Integer countYCL = 0;
+                Integer countWCY = 0;
+                Integer countYQR = 0;
+                Integer countWQR = 0;
+
+                searchParams.put("code", area.getCode() + "%");
+                Page<SpecialOpinion> page = specialOpinionService.pageSearch(searchParams, 1, 10000, false, sortList);
+                for (SpecialOpinion specialOpinion : page.getResult()) {
+                    if (specialOpinion.getIsSatisfied() != null && specialOpinion.getIsSatisfied()) {
+                        countMY++;
+                    } else {
+                        countBMY++;
+                    }
+                    if (specialOpinion.getOpinionStatus() != null && specialOpinion.getOpinionStatus()) {
+                        countYCL++;
+                    } else {
+                        countWCY++;
+                    }
+                    if (specialOpinion.getConfirmStatus() != null && specialOpinion.getConfirmStatus() == 1) {
+                        countYQR++;
+                    } else {
+                        countWQR++;
+                    }
+                }
+
+                SpecialOpinionReportDTO specialOpinionReportDTO = new SpecialOpinionReportDTO();
+                specialOpinionReportDTO.setArea(area.getName());
+                specialOpinionReportDTO.setCountMY(countMY);
+                specialOpinionReportDTO.setCountBMY(countBMY);
+                specialOpinionReportDTO.setCountYCL(countYCL);
+                specialOpinionReportDTO.setCountWCL(countWCY);
+                specialOpinionReportDTO.setCountYQR(countYQR);
+                specialOpinionReportDTO.setCountWQR(countWQR);
+                list.add(specialOpinionReportDTO);
+            }
+        }
+
+        msgResult.setResult(true);
+        msgResult.setData(list);
+
+        return msgResult;
+    }
+
+    @ApiOperation(value="列表")
+    @RequestMapping(value = "pageListTodo",method = RequestMethod.POST)
+    public MessageResult<Map> pageListTodo(
+            String connectPhone, Date[] reportDate,
+            @RequestParam(value="pageIndex",defaultValue="1") int pageIndex,
+            @RequestParam(value="pageSize",defaultValue="20") int pageSize,
+            @RequestAttribute String subject){
+        MessageResult<Map> msgResult = new MessageResult<>();
+
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("create_time","desc"));
+
+        Map<String,Object> searchParams = new HashMap<>();
+        User user = userService.get(subject);
+        if(StringUtils.isNotEmpty(user.getOrgId())) {
+            searchParams.put("orgId", user.getOrgId());
+        }
+        else{
+            searchParams.put("orgId", "0");
+        }
+
+        if (StringUtils.isNotEmpty(connectPhone)) {
+            searchParams.put("connectPhone","%" + connectPhone + "%");
+        }
+
+        if (reportDate.length > 0) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            Calendar calendar = new GregorianCalendar();
+            calendar.setTime(reportDate[1]);
+            calendar.add(calendar.DATE,1);
+
+            searchParams.put("reportDateStart",sdf.format(reportDate[0]));
+            searchParams.put("reportDateEnd",sdf.format(calendar.getTime()));
+        }
+
+        Page<SpecialOpinion> page = specialOpinionService.pageSearchTodo(searchParams,pageIndex,pageSize,true,sortList);
+
+        msgResult.setResult(true);
+        msgResult.setData(PojoUtils.pageWrapper(page));
+
+        return msgResult;
+    }
+
+    @ApiOperation(value="意见待办处理")
+    @RequestMapping(value = "saveTodo",method = RequestMethod.POST)
+    public MessageResult saveTodo(String stepStatusId, String content, @RequestAttribute String subject){
+        MessageResult msgResult = new MessageResult<>();
+
+        try {
+            SpecialStepStatus specialStepStatus = specialStepStatusService.get(stepStatusId);
+            specialStepStatus.setUserId(subject);
+            specialStepStatus.setContent(content);
+            specialStepStatus.setStatus(true);
+            specialStepStatus.setUpdateBy(subject);
+            specialStepStatus.setUpdateTime(new Date());
+            specialStepStatusService.update(specialStepStatus);
+
+            msgResult.setResult(true);
+        }
+        catch (Exception exception) {
+            msgResult.setResult(false);
+            msgResult.setMessage(exception.getMessage());
+        }
+
+        return msgResult;
+    }
+
+    @ApiOperation(value="导出报表")
+    @RequestMapping(value = "reportXls",method = RequestMethod.POST)
+    public String reportXls(@RequestBody SpecialOpinionReportDTO specialOpinionReportDTO){
+        String downloadUrl = "";
+
+        //新建文档
+        Workbook workbook = new HSSFWorkbook();
+        Sheet sheet = workbook.createSheet();
+
+        //单元格样式
+        sheet.setDefaultColumnWidth(15);
+        sheet.setDefaultRowHeight((short) 400);
+
+        Font fontTitle = workbook.createFont();
+        fontTitle.setFontName("宋体");
+        fontTitle.setFontHeightInPoints((short) 11);
+        fontTitle.setBold(true);
+
+        CellStyle cellStyleTitle = workbook.createCellStyle();
+        cellStyleTitle.setBorderTop(BorderStyle.THIN);
+        cellStyleTitle.setBorderBottom(BorderStyle.THIN);
+        cellStyleTitle.setBorderLeft(BorderStyle.THIN);
+        cellStyleTitle.setBorderRight(BorderStyle.THIN);
+        cellStyleTitle.setVerticalAlignment(VerticalAlignment.CENTER);
+        cellStyleTitle.setAlignment(HorizontalAlignment.CENTER);
+        cellStyleTitle.setFont(fontTitle);
+
+        Font fontContent = workbook.createFont();
+        fontContent.setFontName("宋体");
+        fontContent.setFontHeightInPoints((short) 11);
+
+        CellStyle cellStyleContent = workbook.createCellStyle();
+        cellStyleContent.setBorderTop(BorderStyle.THIN);
+        cellStyleContent.setBorderBottom(BorderStyle.THIN);
+        cellStyleContent.setBorderLeft(BorderStyle.THIN);
+        cellStyleContent.setBorderRight(BorderStyle.THIN);
+        cellStyleContent.setVerticalAlignment(VerticalAlignment.CENTER);
+        cellStyleContent.setAlignment(HorizontalAlignment.CENTER);
+        cellStyleContent.setFont(fontContent);
+
+        //表头
+        Row rowTitle = sheet.createRow(0);
+        String[] titles = new String[]{"区域","满意","不满意","已处理","未处理","已确认","未确认"};
+        for (int i=0;i<titles.length;i++) {
+            Cell cell = rowTitle.createCell(i);
+            cell.setCellValue(titles[i]);
+            cell.setCellStyle(cellStyleTitle);
+        }
+
+        //写入数据
+        for(int i=0; i<specialOpinionReportDTO.getTableData().size(); i++){
+            SpecialOpinionReportDTO dto = specialOpinionReportDTO.getTableData().get(i);
+
+            Row row = sheet.createRow(i+1);
+            row.createCell(0);
+            row.createCell(1);
+            row.createCell(2);
+            row.createCell(3);
+            row.createCell(4);
+            row.createCell(5);
+            row.createCell(6);
+
+            row.getCell(0).setCellValue(dto.getArea());
+            row.getCell(1).setCellValue(dto.getCountMY());
+            row.getCell(2).setCellValue(dto.getCountBMY());
+            row.getCell(3).setCellValue(dto.getCountYCL());
+            row.getCell(4).setCellValue(dto.getCountWCL());
+            row.getCell(5).setCellValue(dto.getCountYQR());
+            row.getCell(6).setCellValue(dto.getCountWQR());
+
+            row.getCell(0).setCellStyle(cellStyleContent);
+            row.getCell(1).setCellStyle(cellStyleContent);
+            row.getCell(2).setCellStyle(cellStyleContent);
+            row.getCell(3).setCellStyle(cellStyleContent);
+            row.getCell(4).setCellStyle(cellStyleContent);
+            row.getCell(5).setCellStyle(cellStyleContent);
+            row.getCell(6).setCellStyle(cellStyleContent);
+        }
+
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        try {
+            workbook.write(output);
+
+            byte[] buffer = output.toByteArray();
+            ByteArrayInputStream input = new ByteArrayInputStream(buffer);
+
+            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmm");
+            String now = sdf2.format(new Date());
+            String fileName = "群众评议-" + now + ".xls";
+            downloadUrl = OSSUtil.upload(ossConfig,"InsuranceReport",fileName,input);
+        }
+        catch (Exception ex){
+            logger.error(ex.getMessage(),ex);
+        }
+
+        return downloadUrl;
+    }
+
+    @ApiOperation(value="步进")
+    @PostMapping("nextStep")
+    @Transactional(rollbackFor = Exception.class)
+    public MessageResult nextStep(@RequestBody NextStepDTO nextStepDTO, @RequestAttribute String subject){
+        MessageResult msgResult = new MessageResult<>();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
+        try {
+            //反馈意见
+            SpecialOpinion specialOpinion = specialOpinionService.get(nextStepDTO.getOpinionId());
+            specialOpinion.setConfirmStatus(1);
+            specialOpinion.setAllotedDate(sdf.parse(nextStepDTO.getAllotedDate()));
+            specialOpinionService.update(specialOpinion);
+
+            //反馈意见附件
+            for(AttachmentDTO dto : nextStepDTO.getAttList()) {
+                SpecialAttachment specialAttachment = new SpecialAttachment();
+                specialAttachment.setId(UUID.randomUUID().toString());
+                specialAttachment.setSpecialOpinionId(specialOpinion.getId());
+                specialAttachment.setAttachmentType("3");
+                specialAttachment.setAttachmentTitle(dto.getName());
+                specialAttachment.setAttachmentUrl(dto.getUrl());
+                specialAttachment.setCreateBy(subject);
+                specialAttachment.setCreateTime(new Date());
+                specialAttachmentService.insert(specialAttachment);
+            }
+
+            //反馈意见步进
+            SpecialStep specialStep = new SpecialStep();
+            specialStep.setId(UUID.randomUUID().toString());
+            specialStep.setSpecialOpinionId(specialOpinion.getId());
+            specialStep.setAllotedDate(sdf.parse(nextStepDTO.getAllotedDate()));
+            specialStep.setDelFlag(false);
+            specialStep.setCreateTime(new Date());
+            specialStep.setCreateBy(subject);
+            specialStepService.insert(specialStep);
+
+            //反馈意见反馈
+            for(String orgId : nextStepDTO.getOrgIds()) {
+                SpecialStepStatus specialStepStatus = new SpecialStepStatus();
+                specialStepStatus.setId(UUID.randomUUID().toString());
+                specialStepStatus.setSpecialStepId(specialStep.getId());
+                specialStepStatus.setOrgId(orgId);
+                specialStepStatus.setStatus(false);
+                specialStepStatus.setAllotedDate(sdf.parse(nextStepDTO.getAllotedDate()));
+                specialStepStatus.setDelFlag(false);
+                specialStepStatus.setCreateTime(new Date());
+                specialStepStatus.setCreateBy(subject);
+                specialStepStatusService.insert(specialStepStatus);
+            }
+
+            //发送交办单位短信
+            String MessageContent = "";
+            MessageContent = "【双优督办】您有一条待办反馈,请登录双优督办平台电脑端查看。(http://39.104.144.104/excellent-portal)";
+            sendSMSing(MessageContent, nextStepDTO.getOrgIds(), null);
+
+            msgResult.setResult(true);
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+
+    private void sendSMSing(String MessageContent, String[] orgIds, String ScheduleTime){
+        if(orgIds.length > 0) {
+            List<String> phones = new ArrayList<>();
+            for(String orgId : orgIds){
+                List<User> userList = userService.findListByOrgId(orgId);
+                for(User user : userList){
+                    if(StringUtils.isNotEmpty(user.getPhone())) {
+                        phones.add(user.getPhone().replace(" ",""));
+                    }
+                }
+            }
+            SMSUtil.sendSMS(MessageContent, StringUtils.join(phones.toArray(), ","), ScheduleTime);
+        }
+    }
+
+    @ApiOperation(value="完成")
+    @PostMapping("finish")
+    @Transactional(rollbackFor = Exception.class)
+    public MessageResult finish(String specialOpinionId, @RequestAttribute String subject){
+        MessageResult msgResult = new MessageResult<>();
+        try {
+            //反馈意见
+            SpecialOpinion specialOpinion = specialOpinionService.get(specialOpinionId);
+            specialOpinion.setConfirmStatus(1);
+            specialOpinion.setOpinionStatus(true);
+            specialOpinion.setUpdateBy(subject);
+            specialOpinion.setUpdateTime(new Date());
+            specialOpinionService.update(specialOpinion);
+
+            msgResult.setResult(true);
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+
+    @ApiOperation(value="完成")
+    @PostMapping("noAvail")
+    public MessageResult noAvail(String specialOpinionId, @RequestAttribute String subject){
+        MessageResult msgResult = new MessageResult<>();
+        try {
+            //反馈意见
+            SpecialOpinion specialOpinion = specialOpinionService.get(specialOpinionId);
+            specialOpinion.setConfirmStatus(2);
+            specialOpinion.setUpdateBy(subject);
+            specialOpinion.setUpdateTime(new Date());
+            specialOpinionService.update(specialOpinion);
+
+            msgResult.setResult(true);
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+
+    private String parentFullName(String parentId){
+        String fullName = "";
+
+        Area area = areaService.get(parentId);
+        if(StringUtils.isNotEmpty(area.getParentId())){
+            fullName = parentFullName(area.getParentId()) + "-" + area.getName();
+        }
+        else {
+            fullName = area.getName();
+        }
+
+        return fullName;
+    }
+}

+ 3 - 1
web/src/main/java/com/jpsoft/excellent/modules/open/FeedbackOpinionApiController.java

@@ -123,7 +123,9 @@ public class FeedbackOpinionApiController {
             }
             feedbackOpinion.setCause(cause);
             feedbackOpinion.setContent(content);
-            feedbackOpinion.setAppendix(String.join(",",appendixs));
+            if(appendixs != null) {
+                feedbackOpinion.setAppendix(String.join(",", appendixs));
+            }
             feedbackOpinion.setDelFlag(false);
             feedbackOpinion.setCreateTime(new Date());
             feedbackOpinion.setOpinionStatus(false);

+ 1 - 1
web/src/main/java/com/jpsoft/excellent/modules/open/OfficeOpinionApiController.java

@@ -78,7 +78,7 @@ public class OfficeOpinionApiController {
                 officeOpinion.setIsSatisfied(false);
 
                 String MessageContent = "【双优督办】干部监督评议有一条投诉,请查收。(http://39.104.144.104/excellent-portal)";
-                String UserNumber = "13677200818,13647155484";
+                String UserNumber = "15272389231,13647155484";
                 SMSUtil.sendSMS(MessageContent, UserNumber, null);
             }
             else{

+ 319 - 0
web/src/main/java/com/jpsoft/excellent/modules/open/SpecialOpinionApiController.java

@@ -0,0 +1,319 @@
+package com.jpsoft.excellent.modules.open;
+
+import com.github.pagehelper.Page;
+import com.jpsoft.excellent.config.OSSConfig;
+import com.jpsoft.excellent.modules.base.entity.Area;
+import com.jpsoft.excellent.modules.base.entity.SpecialOpinion;
+import com.jpsoft.excellent.modules.base.entity.WorkStation;
+import com.jpsoft.excellent.modules.base.entity.WorkWindow;
+import com.jpsoft.excellent.modules.base.service.AreaService;
+import com.jpsoft.excellent.modules.base.service.SpecialOpinionService;
+import com.jpsoft.excellent.modules.base.service.WorkStationService;
+import com.jpsoft.excellent.modules.base.service.WorkWindowService;
+import com.jpsoft.excellent.modules.common.dto.MessageResult;
+import com.jpsoft.excellent.modules.common.dto.Sort;
+import com.jpsoft.excellent.modules.common.utils.OSSUtil;
+import com.jpsoft.excellent.modules.common.utils.SMSUtil;
+import com.jpsoft.excellent.modules.sys.entity.DataDictionary;
+import com.jpsoft.excellent.modules.sys.entity.SysLog;
+import com.jpsoft.excellent.modules.sys.service.DataDictionaryService;
+import com.jpsoft.excellent.modules.sys.service.SysLogService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import sun.misc.BASE64Decoder;
+
+import java.io.ByteArrayInputStream;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@RestController
+@RequestMapping("/open/specialOpinionApi")
+@Api(description = "移动端")
+public class SpecialOpinionApiController {
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Autowired
+    private OSSConfig ossConfig;
+    @Autowired
+    private SysLogService sysLogService;
+    @Autowired
+    private DataDictionaryService dataDictionaryService;
+    @Autowired
+    private WorkStationService workStationService;
+    @Autowired
+    private WorkWindowService workWindowService;
+    @Autowired
+    private SpecialOpinionService specialOpinionService;
+    @Autowired
+    private AreaService areaService;
+
+    @ApiOperation(value = "区域列表")
+    @PostMapping("areaList")
+    public List<Area> areaList(String name) {
+        Map<String, Object> searchParams = new HashMap<>();
+        if(StringUtils.isNotEmpty(name)) {
+            searchParams.put("name", "%" + name + "%");
+        }
+
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("parent_id", "asc"));
+        sortList.add(new Sort("create_time", "asc"));
+
+        Page<Area> page = areaService.pageSearch(searchParams,1,1000,false,sortList);
+
+        return page.getResult();
+    }
+
+    @ApiOperation(value="站点列表")
+    @PostMapping("stationList")
+    public List<WorkStation> stationList(String areaId){
+        Map<String,Object> searchParams = new HashMap<>();
+
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("a.area_id","asc"));
+        sortList.add(new Sort("a.create_time","asc"));
+
+        if (StringUtils.isNotEmpty(areaId)) {
+            Area area = areaService.get(areaId);
+            searchParams.put("code", area.getCode() + "%");
+        }
+
+        Page<WorkStation> page = workStationService.pageSearch(searchParams,1,10000,false,sortList);
+
+        return page.getResult();
+    }
+
+    @ApiOperation(value="获取站点")
+    @PostMapping("detail")
+    public MessageResult<WorkStation> detail(String id){
+        MessageResult<WorkStation> msgResult = new MessageResult<>();
+
+        try {
+            WorkStation workStation = workStationService.get(id);
+            Area area = areaService.get(workStation.getAreaId());
+            if(area != null){
+                workStation.setAreaName(area.getName());
+            }
+
+            if (workStation != null) {
+                msgResult.setResult(true);
+                msgResult.setData(workStation);
+            } else {
+                msgResult.setResult(false);
+                msgResult.setMessage("数据库不存在该记录!");
+            }
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+
+    @ApiOperation(value="添加整治活动信息")
+    @PostMapping("add")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name="connect", value="联系人", required=true, paramType="query"),
+            @ApiImplicitParam(name="connectPhone", value="联系电话", required=true, paramType="query"),
+            @ApiImplicitParam(name="workStationId", value="站点编号", required=true, paramType="query"),
+            @ApiImplicitParam(name="window", value="窗口", required=true, paramType="query"),
+            @ApiImplicitParam(name="cause", value="原因", required=true, paramType="query"),
+            @ApiImplicitParam(name="content", value="内容", paramType="query"),
+            @ApiImplicitParam(name="appendix", value="附件", paramType="query"),
+    })
+    public MessageResult<SpecialOpinion> add(String connect,String connectPhone,String workStationId,String window,String cause,String content,String[] appendixs){
+        MessageResult<SpecialOpinion> msgResult = new MessageResult<>();
+
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
+            String lastSort = specialOpinionService.getLastSort(sdf.format(new Date()) + "%");
+            if(lastSort == null){
+                lastSort = sdf.format(new Date()) + "000001";
+            }
+            else{
+                lastSort = sdf.format(new Date()) + String.format("%06d",Integer.parseInt(lastSort.substring(4)) + 1);
+            }
+
+            SpecialOpinion specialOpinion = new SpecialOpinion();
+            specialOpinion.setId(UUID.randomUUID().toString());
+            specialOpinion.setSort(lastSort);
+            specialOpinion.setConnect(connect);
+            specialOpinion.setConnectPhone(connectPhone);
+            specialOpinion.setWorkStationId(workStationId);
+            specialOpinion.setWindow(window);
+            specialOpinion.setCause(cause);
+            specialOpinion.setContent(content);
+            if(appendixs != null) {
+                specialOpinion.setAppendix(String.join(",", appendixs));
+            }
+            specialOpinion.setDelFlag(false);
+            specialOpinion.setCreateTime(new Date());
+            specialOpinion.setOpinionStatus(false);
+            specialOpinion.setConfirmStatus(0);
+            
+            int affectCount = specialOpinionService.insert(specialOpinion);
+
+            if (affectCount > 0) {
+                msgResult.setResult(true);
+                msgResult.setData(specialOpinion);
+            } else {
+                msgResult.setResult(false);
+                msgResult.setMessage("数据库添加失败");
+            }
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+
+//    @PostMapping("uploadBase64")
+//    @ResponseBody
+//    @ApiOperation(value = "员工照片上传")
+//    @ApiImplicitParams({
+//            @ApiImplicitParam(name = "photoName", value = "照片名称", required = true, paramType = "form"),
+//            @ApiImplicitParam(name = "photoBase64Data", value = "员工照片base64编码", required = true, paramType = "form")
+//    })
+//    public MessageResult<String> uploadBase64(String photoName, String photoBase64Data) {
+//        MessageResult<String> messageResult = new MessageResult<>();
+//
+//        SysLog sysLog = new SysLog();
+//        sysLog.setPointcut("反馈图片上传");
+//
+//        try {
+//            sysLog.setRemark("base64 照片大小:" + photoBase64Data.length());
+//
+//            //前50个字符
+//            if (StringUtils.isNotEmpty(photoBase64Data)) {
+//                sysLog.setData(photoBase64Data.substring(0, Math.min(photoBase64Data.length(), 50)));
+//            }
+//
+//            BASE64Decoder decoder = new BASE64Decoder();
+//
+//            String[] arr = photoBase64Data.split(",");
+//
+//            byte[] imgData = decoder.decodeBuffer(arr[1]);
+//
+//            for (int i = 0; i < imgData.length; ++i) {
+//                if (imgData[i] < 0) {// 调整异常数据
+//                    imgData[i] += 256;
+//                }
+//            }
+//
+//            ByteArrayInputStream inputStream = new ByteArrayInputStream(imgData);
+//
+//            if (StringUtils.isEmpty(photoName)) {
+//                photoName = "1.jpg";
+//            }
+//
+//            String retFileUrl = OSSUtil.upload(ossConfig, "/SpecialOpinion", photoName, inputStream);
+//
+//            messageResult.setResult(true);
+//            messageResult.setData(retFileUrl);
+//            messageResult.setCode(200);
+//
+//            sysLog.setUrl(retFileUrl);
+//        } catch (Exception e) {
+//            logger.error(e.getMessage(), e);
+//
+//            messageResult.setResult(false);
+//            messageResult.setMessage(e.getMessage());
+//
+//            sysLog.setRemark(sysLog.getRemark() + "," + e.getMessage());
+//        }
+//
+//        sysLog.setCreateTime(new Date());
+//        sysLogService.insert(sysLog);
+//
+//        return messageResult;
+//    }
+
+    @ApiOperation(value="获取原因")
+    @PostMapping("reasonList")
+    public List<String> reasonList(String catalogName){
+        List<DataDictionary> dictionaryList = dataDictionaryService.findByCatalogName(catalogName);
+        List<String> names = new ArrayList<>();
+        for(DataDictionary dataDictionary : dictionaryList){
+            names.add(dataDictionary.getName());
+        }
+
+        return names;
+    }
+
+//    @ApiOperation(value="发送验证码")
+//    @PostMapping("sendRQCode")
+//    public Boolean sendRQCode(String phone,String rqCode){
+//        String MessageContent = String.format("【双优督办】优化营商环境专项整治活动验证码:%s。",rqCode);
+//        SMSUtil.sendSMS(MessageContent, phone, null);
+//        return true;
+//    }
+
+    @ApiOperation(value="获取窗口")
+    @PostMapping("windowList")
+    public List<String> windowList(String stationId){
+        Map<String,Object> searchParams = new HashMap<>();
+
+        List<Sort> sortList = new ArrayList<>();
+        sortList.add(new Sort("a.station_id","asc"));
+        sortList.add(new Sort("a.update_time","desc"));
+
+        if (StringUtils.isNotEmpty(stationId)) {
+            searchParams.put("stationId",stationId);
+        }
+
+        Page<WorkWindow> page = workWindowService.pageSearch(searchParams,1,10000,false,sortList);
+
+        List<String> names = new ArrayList<>();
+        for(WorkWindow workWindow : page.getResult()){
+            names.add(workWindow.getWindowName());
+        }
+
+        return names;
+    }
+
+    @ApiOperation(value="历史记录")
+    @PostMapping("historyList")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name="phone", value="手机号码", required=true, paramType="query"),
+    })
+    public MessageResult historyList(String phone){
+        MessageResult msgResult = new MessageResult<>();
+
+        try {
+            Map<String, Object> searchParams = new HashMap<>();
+            if (StringUtils.isNotEmpty(phone)) {
+                searchParams.put("connectPhone",phone);
+            }
+
+            List<Sort> sortList = new ArrayList<>();
+            sortList.add(new Sort("create_time", "desc"));
+
+            Page<SpecialOpinion> page = specialOpinionService.pageSearch(searchParams, 1, 10000, false, sortList);
+
+            msgResult.setResult(true);
+            msgResult.setData(page.getResult());
+        }
+        catch(Exception ex){
+            logger.error(ex.getMessage(),ex);
+
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
+
+        return msgResult;
+    }
+}

+ 5 - 5
web/src/main/resources/application-dev.yml

@@ -5,12 +5,12 @@ server:
 
 spring:
   datasource:
-#    url: jdbc:log4jdbc:mysql://39.104.144.104:3308/double_excellent?autoReconnect=true&characterEncoding=utf8&serverTimezone=GMT%2B8
-#    username: root
-#    password: jpsoft8121234
-    url: jdbc:log4jdbc:mysql://192.168.33.20:3306/double_excellent?autoReconnect=true&characterEncoding=utf8&serverTimezone=GMT%2B8
+    url: jdbc:log4jdbc:mysql://39.104.144.104:3308/double_excellent?autoReconnect=true&characterEncoding=utf8&serverTimezone=GMT%2B8
     username: root
-    password: jpsoft2016
+    password: jpsoft8121234
+#    url: jdbc:log4jdbc:mysql://192.168.33.20:3306/double_excellent?autoReconnect=true&characterEncoding=utf8&serverTimezone=GMT%2B8
+#    username: root
+#    password: jpsoft2016
   devtools:
     add-properties: false
     restart: