albertshaw 8 years ago
parent
commit
ae893bb693

+ 10 - 0
schema/20180202-sales-report.sql

@@ -0,0 +1,10 @@
+CREATE TABLE `daily_sales_report` (
+  `id` int(10) NOT NULL AUTO_INCREMENT,
+  `admin_id` varchar(36) DEFAULT NULL COMMENT '员工id',
+  `dep_id` varchar(36) DEFAULT NULL COMMENT '部门id',
+  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '统计日期',
+  `order_count` int(8) DEFAULT '0' COMMENT '销售签单数量',
+  `order_amount` decimal(12,2) DEFAULT '0.00' COMMENT '销售签单总额',
+  PRIMARY KEY (`id`),
+  KEY `timeIdx` (`create_time`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;

+ 0 - 1
src/main/java/com/goafanti/common/bo/Result.java

@@ -11,7 +11,6 @@ public class Result {
 	private Serializable token;
 	public Result() {
 		this.token = SecurityUtils.getSubject().getSession().getId();
-		System.out.println("返回 token=============="+token);
 	}
 
 	public Result(Object data) {

+ 10 - 4
src/main/java/com/goafanti/common/constant/AFTConstants.java

@@ -14,12 +14,12 @@ public class AFTConstants {
 	public static final String	INITIALPASSWORD						= "123456";				// 初始密码
 
 	public static final String	SUPERADMIN							= "999999";				// 超级管理员
-	
-	public static final String  APPROVAL_DECISION					= "99999";				//特批决策者
 
-	public static final String	AREAADMIN							= "";				// 地区管理员
+	public static final String	APPROVAL_DECISION					= "99999";				//特批决策者
 
-	public static final String	AUDITORADMIN						= "";				// 审核员
+	public static final String	AREAADMIN							= "";					// 地区管理员
+
+	public static final String	AUDITORADMIN						= "";					// 审核员
 
 	public static final String	MANAGERADMIN						= "";					// 客户经理
 
@@ -99,4 +99,10 @@ public class AFTConstants {
 	public static final String	ORGANIZATION_TYPE_DEPARTMENT		= "1";
 	/**组织类型-团队*/
 	public static final String	ORGANIZATION_TYPE_TEAM				= "2";
+
+	public static final String	DAILY								= "daily";
+	public static final String	WEEKLY								= "weekly";
+	public static final String	MONTHLY								= "monthly";
+	public static final String	QUARTERLY							= "quarterly";
+	public static final String	ANNUALLY							= "annually";
 }

+ 34 - 0
src/main/java/com/goafanti/common/dao/DailySalesReportMapper.java

@@ -0,0 +1,34 @@
+package com.goafanti.common.dao;
+
+import java.util.Date;
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import org.springframework.ui.ModelMap;
+
+import com.goafanti.common.model.DailySalesReport;
+import com.goafanti.report.bo.DepartmentSalesReportBO;
+import com.goafanti.report.bo.PersonalSalesReportBO;
+
+public interface DailySalesReportMapper {
+
+	DailySalesReport selectByPrimaryKey(Long id);
+
+	int insertSalesReports(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
+
+	List<PersonalSalesReportBO> selectSalesPersonalReports(@Param("startTime") Date startTime,
+			@Param("endTime") Date endTime, @Param("pageNo") Integer pageNo, @Param("pageSize") Integer pageSize,
+			@Param("orderField") String orderField, @Param("order") String order,
+			@Param("countField") String countField, @Param("amountField") String amountField,
+			@Param("depName") String depName, @Param("name") String name, @Param("position") String position);
+
+	List<ModelMap> selectSalesPersonalExtraReports(@Param("startTime") Date startTime, @Param("endTime") Date endTime,
+			@Param("ids") List<String> ids);
+
+	ModelMap selectTotalReports(@Param("startTime") Date startTime, @Param("endTime") Date endTime);
+
+	List<DepartmentSalesReportBO> selectSalesDepartmentReports();
+
+	List<ModelMap> selectSalesDepartmentExtraReports(@Param("startTime") Date startTime,
+			@Param("endTime") Date endTime);
+}

+ 89 - 0
src/main/java/com/goafanti/common/mapper/DailySalesReportMapper.xml

@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.goafanti.common.dao.DailySalesReportMapper">
+  <resultMap id="BaseResultMap" type="com.goafanti.common.model.DailySalesReport">
+    <id column="id" jdbcType="INTEGER" property="id" />
+    <result column="admin_id" jdbcType="VARCHAR" property="adminId" />
+    <result column="dep_id" jdbcType="VARCHAR" property="depId" />
+    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+    <result column="order_count" jdbcType="INTEGER" property="orderCount" />
+    <result column="order_amount" jdbcType="DECIMAL" property="orderAmount" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    id, admin_id, dep_id, create_time, order_count, order_amount
+  </sql>
+  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from daily_sales_report
+    where id = #{id,jdbcType=INTEGER}
+  </select>
+  <insert id="insertSalesReports">
+    insert into daily_sales_report 
+    (admin_id, dep_id, order_count, order_amount) 
+    SELECT o.salesman_id as admin_id, a.department_id as dep_id,
+	count(o.order_no) as order_count, sum(o.order_amount) as order_amount
+	FROM aft.t_order o
+	left join aft.admin a on o.salesman_id=a.id
+	where o.order_status=3 and o.sign_time &gt;= #{startTime,jdbcType=TIMESTAMP} and o.sign_time &lt; #{endTime,jdbcType=TIMESTAMP}
+	group by o.salesman_id, a.department_id;
+  </insert>
+  
+  <select id="selectSalesPersonalReports" resultType="com.goafanti.report.bo.PersonalSalesReportBO">
+    SELECT a.id, a.name, dm.name as departmentName, a.position, a.create_time as enrollTime, 
+	sum(dsr.order_count) as ${countField}, sum(dsr.order_amount) as ${amountField}
+	FROM admin a
+	left join daily_sales_report dsr on dsr.admin_id = a.id 
+	left join department_management dm on dm.id = dsr.dep_id 
+	where (dsr.create_time is null or (dsr.create_time &gt;= #{startTime,jdbcType=TIMESTAMP} and dsr.create_time &lt; #{endTime,jdbcType=TIMESTAMP}))
+	<if test="depName != null">
+		and dm.name like concat(#{depName,jdbcType=VARCHAR},'%')
+	</if>
+	<if test="name != null">
+		and a.name like concat(#{name,jdbcType=VARCHAR},'%')
+	</if>
+	<if test="position != null">
+		and a.position like concat(#{position,jdbcType=VARCHAR},'%')
+	</if>
+	group by a.id, dsr.dep_id, dm.id
+	order by ${orderField} ${order}, a.name asc
+	<if test="pageNo != null and pageSize != null">
+		limit #{pageNo,jdbcType=INTEGER}, #{pageSize,jdbcType=INTEGER}
+    </if>
+  </select>
+  
+  <select id="selectSalesPersonalExtraReports" resultType="org.springframework.ui.ModelMap">
+    SELECT dsr.admin_id as id, sum(dsr.order_count) as order_count, sum(dsr.order_amount) as order_amount
+	FROM daily_sales_report dsr 
+	where dsr.create_time &gt;= #{startTime,jdbcType=TIMESTAMP} and dsr.create_time &lt; #{endTime,jdbcType=TIMESTAMP}
+	<if test="ids != null">
+		and dsr.admin_id in 
+		<foreach item="item" index="index" collection="ids" open="(" separator="," close=")">
+			#{item}
+		</foreach>	
+	</if>
+	group by dsr.admin_id
+  </select>
+  
+  <select id="selectSalesDepartmentReports" resultType="com.goafanti.report.bo.DepartmentSalesReportBO">
+    SELECT dm.id, a.name as managerName, dm.name as departmentName, count(a2.id) as memberCount, dm.super_id as superId
+	FROM department_management dm
+	left join admin a2 on a2.department_id = dm.id 
+	left join admin a on a.id = dm.manager_id
+	group by dm.id, a.id
+	order by dm.name asc
+  </select>
+  
+  <select id="selectSalesDepartmentExtraReports" resultType="org.springframework.ui.ModelMap">
+    SELECT dsr.dep_id as id, sum(dsr.order_count) as order_count, sum(dsr.order_amount) as order_amount
+	FROM daily_sales_report dsr 
+	where dsr.create_time &gt;= #{startTime,jdbcType=TIMESTAMP} and dsr.create_time &lt; #{endTime,jdbcType=TIMESTAMP}
+	group by dsr.dep_id
+  </select>
+  
+  <select id="selectTotalReports" resultType="org.springframework.ui.ModelMap">
+    SELECT sum(dsr.order_count) as totalCount, sum(dsr.order_amount) as totalAmount
+	FROM daily_sales_report dsr 
+	where dsr.create_time &gt;= #{startTime,jdbcType=TIMESTAMP} and dsr.create_time &lt; #{endTime,jdbcType=TIMESTAMP}
+  </select>
+</mapper>

+ 81 - 0
src/main/java/com/goafanti/common/model/DailySalesReport.java

@@ -0,0 +1,81 @@
+package com.goafanti.common.model;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+public class DailySalesReport {
+	private Integer		id;
+
+	/**
+	* 员工id
+	*/
+	private String		adminId;
+
+	/**
+	* 部门id
+	*/
+	private String		depId;
+
+	/**
+	* 统计日期
+	*/
+	private Date		createTime;
+
+	/**
+	* 销售签单数量
+	*/
+	private Integer		orderCount;
+
+	/**
+	* 销售签单总额
+	*/
+	private BigDecimal	orderAmount;
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public String getAdminId() {
+		return adminId;
+	}
+
+	public void setAdminId(String adminId) {
+		this.adminId = adminId;
+	}
+
+	public String getDepId() {
+		return depId;
+	}
+
+	public void setDepId(String depId) {
+		this.depId = depId;
+	}
+
+	public Date getCreateTime() {
+		return createTime;
+	}
+
+	public void setCreateTime(Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public Integer getOrderCount() {
+		return orderCount;
+	}
+
+	public void setOrderCount(Integer orderCount) {
+		this.orderCount = orderCount;
+	}
+
+	public BigDecimal getOrderAmount() {
+		return orderAmount;
+	}
+
+	public void setOrderAmount(BigDecimal orderAmount) {
+		this.orderAmount = orderAmount;
+	}
+}

+ 41 - 0
src/main/java/com/goafanti/common/task/OrderReportTask.java

@@ -0,0 +1,41 @@
+package com.goafanti.common.task;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import javax.annotation.Resource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import com.goafanti.common.utils.LoggerUtils;
+import com.goafanti.report.service.SalesReportServiceImpl;
+
+@Component
+public class OrderReportTask {
+
+	Logger							logger	= LoggerFactory.getLogger(OrderReportTask.class);
+
+	@Resource
+	private SalesReportServiceImpl	dailySalesReportServiceImpl;
+
+	/**
+	 * "0 0 17 * * ?" 每天17点触发一次
+	 */
+	@Scheduled(cron = "0 0 17 * * ?")
+	public void exprireRun() {
+		LoggerUtils.debug(logger, "统计订单报表任务开始");
+		Calendar now = Calendar.getInstance();
+		now.set(Calendar.MILLISECOND, 0);
+		now.set(Calendar.SECOND, 0);
+		now.set(Calendar.MINUTE, 0);
+		Date start = new Calendar.Builder()
+				.setDate(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH) - 1)
+				.setTimeOfDay(17, 0, 0, 0).build().getTime();
+		// 统计从昨天17点到今天17点的数据,算作今日数据
+		int count = dailySalesReportServiceImpl.insertDailyReports(start, now.getTime());
+		LoggerUtils.debug(logger, "统计今日订单【%s】条。", count);
+	}
+}

+ 351 - 327
src/main/java/com/goafanti/common/utils/DateUtils.java

@@ -6,17 +6,17 @@ import java.util.Calendar;
 import java.util.Date;
 
 public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
-	
-	public static final String YEAR_SPAN =  "yearSpan";
-	
-	public static final String QUARTER_SPAN = "quarterSpan";
-	
-	public static final String MONTH_SPAN = "monthSpan";
-
-	public static final String WEEK_SPAN = "weekSpan";
-	
-	public static final String DAY_SPAN = "daySpan";
-	
+
+	public static final String	YEAR_SPAN		= "yearSpan";
+
+	public static final String	QUARTER_SPAN	= "quarterSpan";
+
+	public static final String	MONTH_SPAN		= "monthSpan";
+
+	public static final String	WEEK_SPAN		= "weekSpan";
+
+	public static final String	DAY_SPAN		= "daySpan";
+
 	/**
 	 * Determines how two dates compare up to no more than the specified most
 	 * significant field.
@@ -83,344 +83,343 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
 	public static long truncatedMinuteDiffTo(final Date date1, final Date date2) {
 		return truncatedDiffTo(date1, date2, Calendar.MINUTE) / 60000;
 	}
-	
-    /**
-     * 得到某年某周的第一天
-     *
-     * @param year
-     * @param week
-     * @return
-     */
-    public static Date getFirstDayOfWeek(int year, int week) {
-        week = week - 1;
-        Calendar calendar = Calendar.getInstance();
-        calendar.set(Calendar.YEAR, year);
-        calendar.set(Calendar.MONTH, Calendar.JANUARY);
-        calendar.set(Calendar.DATE, 1);
-
-        Calendar cal = (Calendar) calendar.clone();
-        cal.add(Calendar.DATE, week * 7);
-
-        return getFirstDayOfWeek(cal.getTime());
-    }
-
-    /**
-     * 得到某年某周的最后一天
-     *
-     * @param year
-     * @param week
-     * @return
-     */
-    public static Date getLastDayOfWeek(int year, int week) {
-        week = week - 1;
-        Calendar calendar = Calendar.getInstance();
-        calendar.set(Calendar.YEAR, year);
-        calendar.set(Calendar.MONTH, Calendar.JANUARY);
-        calendar.set(Calendar.DATE, 1);
-        Calendar cal = (Calendar) calendar.clone();
-        cal.add(Calendar.DATE, week * 7);
-
-        return getLastDayOfWeek(cal.getTime());
-    }
-
-    /**
-     * 取得当前日期所在周的第一天
-     *
-     * @param date
-     * @return
-     */
-    public static Date getFirstDayOfWeek(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setFirstDayOfWeek(Calendar.SUNDAY);
-        calendar.setTime(date);
-        calendar.set(Calendar.DAY_OF_WEEK,
-                      calendar.getFirstDayOfWeek()); // Sunday
-        return calendar.getTime();
-    }
-
-    /**
-     * 取得当前日期所在周的最后一天
-     *
-     * @param date
-     * @return
-     */
-    public static Date getLastDayOfWeek(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setFirstDayOfWeek(Calendar.SUNDAY);
-        calendar.setTime(date);
-        calendar.set(Calendar.DAY_OF_WEEK,
-                     calendar.getFirstDayOfWeek() + 6); // Saturday
-        return calendar.getTime();
-    }
-
-    /**
-     * 取得当前日期所在周的前一周最后一天
-     *
-     * @param date
-     * @return
-     */
-    public static Date getLastDayOfLastWeek(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(date);
-        return getLastDayOfWeek(calendar.get(Calendar.YEAR),
-                                calendar.get(Calendar.WEEK_OF_YEAR) - 1);
-    }
-
-    /**
-     * 返回指定日期的月的第一天
-     *
-     * @param year
-     * @param month
-     * @return
-     */
-    public static Date getFirstDayOfMonth(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(date);
-        calendar.set(calendar.get(Calendar.YEAR),
-                     calendar.get(Calendar.MONTH), 1);
-        return calendar.getTime();
-    }
-
-    /**
-     * 返回指定年月的月的第一天
-     *
-     * @param year
-     * @param month
-     * @return
-     */
-    public static Date getFirstDayOfMonth(Integer year, Integer month) {
-        Calendar calendar = Calendar.getInstance();
-        if (year == null) {
-            year = calendar.get(Calendar.YEAR);
-        }
-        if (month == null) {
-            month = calendar.get(Calendar.MONTH);
-        }
-        calendar.set(year, month, 1);
-        return calendar.getTime();
-    }
-
-    /**
-     * 返回指定日期的月的最后一天
-     *
-     * @param year
-     * @param month
-     * @return
-     */
-    public static Date getLastDayOfMonth(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(date);
-        calendar.set(calendar.get(Calendar.YEAR),
-                     calendar.get(Calendar.MONTH), 1);
-        calendar.roll(Calendar.DATE, -1);
-        return calendar.getTime();
-    }
-
-    /**
-     * 返回指定年月的月的最后一天
-     *
-     * @param year
-     * @param month
-     * @return
-     */
-    public static Date getLastDayOfMonth(Integer year, Integer month) {
-        Calendar calendar = Calendar.getInstance();
-        if (year == null) {
-            year = calendar.get(Calendar.YEAR);
-        }
-        if (month == null) {
-            month = calendar.get(Calendar.MONTH);
-        }
-        calendar.set(year, month, 1);
-        calendar.roll(Calendar.DATE, -1);
-        return calendar.getTime();
-    }
-
-    /**
-     * 返回指定日期的上个月的最后一天
-     *
-     * @param year
-     * @param month
-     * @return
-     */
-    public static Date getLastDayOfLastMonth(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(date);
-        calendar.set(calendar.get(Calendar.YEAR),
-                     calendar.get(Calendar.MONTH) - 1, 1);
-        calendar.roll(Calendar.DATE, -1);
-        return calendar.getTime();
-    }
-
-    /**
-     * 返回指定日期的季的第一天
-     *
-     * @param year
-     * @param quarter
-     * @return
-     */
-    public static Date getFirstDayOfQuarter(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(date);
-        return getFirstDayOfQuarter(calendar.get(Calendar.YEAR),
-                                    getQuarterOfYear(date));
-    }
-
-    /**
-     * 返回指定年季的季的第一天
-     *
-     * @param year
-     * @param quarter
-     * @return
-     */
-    public static Date getFirstDayOfQuarter(Integer year, Integer quarter) {
-        Calendar calendar = Calendar.getInstance();
-        Integer month = new Integer(0);
-        if (quarter == 1) {
-            month = 1 - 1;
-        } else if (quarter == 2) {
-            month = 4 - 1;
-        } else if (quarter == 3) {
-            month = 7 - 1;
-        } else if (quarter == 4) {
-            month = 10 - 1;
-        } else {
-            month = calendar.get(Calendar.MONTH);
-        }
-        return getFirstDayOfMonth(year, month);
-    }
-
-    /**
-     * 返回指定日期的季的最后一天
-     *
-     * @param year
-     * @param quarter
-     * @return
-     */
-    public static Date getLastDayOfQuarter(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(date);
-        return getLastDayOfQuarter(calendar.get(Calendar.YEAR),
-                                   getQuarterOfYear(date));
-    }
-
-    /**
-     * 返回指定年季的季的最后一天
-     *
-     * @param year
-     * @param quarter
-     * @return
-     */
-    public static Date getLastDayOfQuarter(Integer year, Integer quarter) {
-        Calendar calendar = Calendar.getInstance();
-        Integer month = new Integer(0);
-        if (quarter == 1) {
-            month = 3 - 1;
-        } else if (quarter == 2) {
-            month = 6 - 1;
-        } else if (quarter == 3) {
-            month = 9 - 1;
-        } else if (quarter == 4) {
-            month = 12 - 1;
-        } else {
-            month = calendar.get(Calendar.MONTH);
-        }
-        return getLastDayOfMonth(year, month);
-    }
-
-    /**
-     * 返回指定日期的上一季的最后一天
-     *
-     * @param year
-     * @param quarter
-     * @return
-     */
-    public static Date getLastDayOfLastQuarter(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(date);
-        return getLastDayOfLastQuarter(calendar.get(Calendar.YEAR),
-                                       getQuarterOfYear(date));
-    }
-
-    /**
-     * 返回指定年季的上一季的最后一天
-     *
-     * @param year
-     * @param quarter
-     * @return
-     */
-    public static Date getLastDayOfLastQuarter(Integer year, Integer quarter) {
-        Calendar calendar = Calendar.getInstance();
-        Integer month = new Integer(0);
-        if (quarter == 1) {
-            month = 12 - 1;
-        } else if (quarter == 2) {
-            month = 3 - 1;
-        } else if (quarter == 3) {
-            month = 6 - 1;
-        } else if (quarter == 4) {
-            month = 9 - 1;
-        } else {
-            month = calendar.get(Calendar.MONTH);
-        }
-        return getLastDayOfMonth(year, month);
-    }
-
-    /**
-     * 返回指定日期的季度
-     *
-     * @param date
-     * @return
-     */
-    public static int getQuarterOfYear(Date date) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(date);
-        return calendar.get(Calendar.MONTH) / 3 + 1;
-    }
- 
-    /**
-     * 返回昨天日期
-     * @return date
-     */
-    public static Date getYesterday(){
-    	  Calendar calendar = Calendar.getInstance();
-    	  calendar.add(Calendar.DATE, -1);
-    	  return calendar.getTime();
-    }
-    
-    /** 
-     *  返回前一年最后一天
-     * @param date
-     * @return
-     */
+
+	/**
+	 * 得到某年某周的第一天
+	 *
+	 * @param year
+	 * @param week
+	 * @return
+	 */
+	public static Date getFirstDayOfWeek(int year, int week) {
+		week = week - 1;
+		Calendar calendar = Calendar.getInstance();
+		calendar.set(Calendar.YEAR, year);
+		calendar.set(Calendar.MONTH, Calendar.JANUARY);
+		calendar.set(Calendar.DATE, 1);
+		Calendar cal = (Calendar) calendar.clone();
+		cal.add(Calendar.DATE, week * 7);
+
+		return getFirstDayOfWeek(cal.getTime());
+	}
+
+	/**
+	 * 得到某年某周的最后一天
+	 *
+	 * @param year
+	 * @param week
+	 * @return
+	 */
+	public static Date getLastDayOfWeek(int year, int week) {
+		week = week - 1;
+		Calendar calendar = Calendar.getInstance();
+		calendar.set(Calendar.YEAR, year);
+		calendar.set(Calendar.MONTH, Calendar.JANUARY);
+		calendar.set(Calendar.DATE, 1);
+		Calendar cal = (Calendar) calendar.clone();
+		cal.add(Calendar.DATE, week * 7);
+
+		return getLastDayOfWeek(cal.getTime());
+	}
+
+	/**
+	 * 取得当前日期所在周的第一天
+	 *
+	 * @param date
+	 * @return
+	 */
+	public static Date getFirstDayOfWeek(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setFirstDayOfWeek(Calendar.SUNDAY);
+		calendar.setTime(date);
+		calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek()); // Sunday
+		setMidnight(calendar);
+		return calendar.getTime();
+	}
+
+	/**
+	 * 取得当前日期所在周的最后一天
+	 *
+	 * @param date
+	 * @return
+	 */
+	public static Date getLastDayOfWeek(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setFirstDayOfWeek(Calendar.SUNDAY);
+		calendar.setTime(date);
+		calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek() + 6); // Saturday
+		setMidnight(calendar);
+		return calendar.getTime();
+	}
+
+	/**
+	 * 取得当前日期所在周的前一周最后一天
+	 *
+	 * @param date
+	 * @return
+	 */
+	public static Date getLastDayOfLastWeek(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		return getLastDayOfWeek(calendar.get(Calendar.YEAR), calendar.get(Calendar.WEEK_OF_YEAR) - 1);
+	}
+
+	/**
+	 * 返回指定日期的月的第一天
+	 *
+	 * @param year
+	 * @param month
+	 * @return
+	 */
+	public static Date getFirstDayOfMonth(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 1);
+		setMidnight(calendar);
+		return calendar.getTime();
+	}
+
+	/**
+	 * 返回指定年月的月的第一天
+	 *
+	 * @param year
+	 * @param month
+	 * @return
+	 */
+	public static Date getFirstDayOfMonth(Integer year, Integer month) {
+		Calendar calendar = Calendar.getInstance();
+		if (year == null) {
+			year = calendar.get(Calendar.YEAR);
+		}
+		if (month == null) {
+			month = calendar.get(Calendar.MONTH);
+		}
+		calendar.set(year, month, 1);
+		setMidnight(calendar);
+		return calendar.getTime();
+	}
+
+	/**
+	 * 返回指定日期的月的最后一天
+	 *
+	 * @param year
+	 * @param month
+	 * @return
+	 */
+	public static Date getLastDayOfMonth(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 1);
+		calendar.roll(Calendar.DATE, -1);
+		setMidnight(calendar);
+		return calendar.getTime();
+	}
+
+	/**
+	 * 返回指定年月的月的最后一天
+	 *
+	 * @param year
+	 * @param month
+	 * @return
+	 */
+	public static Date getLastDayOfMonth(Integer year, Integer month) {
+		Calendar calendar = Calendar.getInstance();
+		if (year == null) {
+			year = calendar.get(Calendar.YEAR);
+		}
+		if (month == null) {
+			month = calendar.get(Calendar.MONTH);
+		}
+		calendar.set(year, month, 1);
+		calendar.roll(Calendar.DATE, -1);
+		setMidnight(calendar);
+		return calendar.getTime();
+	}
+
+	/**
+	 * 返回指定日期的上个月的最后一天
+	 *
+	 * @param year
+	 * @param month
+	 * @return
+	 */
+	public static Date getLastDayOfLastMonth(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) - 1, 1);
+		calendar.roll(Calendar.DATE, -1);
+		setMidnight(calendar);
+		return calendar.getTime();
+	}
+
+	/**
+	 * 返回指定日期的季的第一天
+	 *
+	 * @param year
+	 * @param quarter
+	 * @return
+	 */
+	public static Date getFirstDayOfQuarter(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		return getFirstDayOfQuarter(calendar.get(Calendar.YEAR), getQuarterOfYear(date));
+	}
+
+	/**
+	 * 返回指定年季的季的第一天
+	 *
+	 * @param year
+	 * @param quarter
+	 * @return
+	 */
+	public static Date getFirstDayOfQuarter(Integer year, Integer quarter) {
+		Calendar calendar = Calendar.getInstance();
+		Integer month = new Integer(0);
+		if (quarter == 1) {
+			month = 1 - 1;
+		} else if (quarter == 2) {
+			month = 4 - 1;
+		} else if (quarter == 3) {
+			month = 7 - 1;
+		} else if (quarter == 4) {
+			month = 10 - 1;
+		} else {
+			month = calendar.get(Calendar.MONTH);
+		}
+		return getFirstDayOfMonth(year, month);
+	}
+
+	/**
+	 * 返回指定日期的季的最后一天
+	 *
+	 * @param year
+	 * @param quarter
+	 * @return
+	 */
+	public static Date getLastDayOfQuarter(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		return getLastDayOfQuarter(calendar.get(Calendar.YEAR), getQuarterOfYear(date));
+	}
+
+	/**
+	 * 返回指定年季的季的最后一天
+	 *
+	 * @param year
+	 * @param quarter
+	 * @return
+	 */
+	public static Date getLastDayOfQuarter(Integer year, Integer quarter) {
+		Calendar calendar = Calendar.getInstance();
+		Integer month = new Integer(0);
+		if (quarter == 1) {
+			month = 3 - 1;
+		} else if (quarter == 2) {
+			month = 6 - 1;
+		} else if (quarter == 3) {
+			month = 9 - 1;
+		} else if (quarter == 4) {
+			month = 12 - 1;
+		} else {
+			month = calendar.get(Calendar.MONTH);
+		}
+		return getLastDayOfMonth(year, month);
+	}
+
+	/**
+	 * 返回指定日期的上一季的最后一天
+	 *
+	 * @param year
+	 * @param quarter
+	 * @return
+	 */
+	public static Date getLastDayOfLastQuarter(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		return getLastDayOfLastQuarter(calendar.get(Calendar.YEAR), getQuarterOfYear(date));
+	}
+
+	/**
+	 * 返回指定年季的上一季的最后一天
+	 *
+	 * @param year
+	 * @param quarter
+	 * @return
+	 */
+	public static Date getLastDayOfLastQuarter(Integer year, Integer quarter) {
+		Calendar calendar = Calendar.getInstance();
+		Integer month = new Integer(0);
+		if (quarter == 1) {
+			month = 12 - 1;
+		} else if (quarter == 2) {
+			month = 3 - 1;
+		} else if (quarter == 3) {
+			month = 6 - 1;
+		} else if (quarter == 4) {
+			month = 9 - 1;
+		} else {
+			month = calendar.get(Calendar.MONTH);
+		}
+		return getLastDayOfMonth(year, month);
+	}
+
+	/**
+	 * 返回指定日期的季度
+	 *
+	 * @param date
+	 * @return
+	 */
+	public static int getQuarterOfYear(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		return calendar.get(Calendar.MONTH) / 3 + 1;
+	}
+
+	/**
+	 * 返回昨天日期
+	 * @return date
+	 */
+	public static Date getYesterday() {
+		Calendar calendar = Calendar.getInstance();
+		calendar.add(Calendar.DATE, -1);
+		setMidnight(calendar);
+		return calendar.getTime();
+	}
+
+	/** 
+	 *  返回前一年最后一天
+	 * @param date
+	 * @return
+	 */
 	public static Date getLastDayOfLastYear(Date date) {
 		Calendar calendar = Calendar.getInstance();
 		return getLastDayOfYear(calendar.get(Calendar.YEAR) - 1);
 	}
-	
+
 	/**
 	 * 返回指定年的最后一天
 	 * @param year
 	 * @return
 	 */
-	public static Date getLastDayOfYear(int year){
+	public static Date getLastDayOfYear(int year) {
 		Calendar calendar = Calendar.getInstance();
 		calendar.set(Calendar.YEAR, year - 1);
 		calendar.roll(Calendar.DAY_OF_YEAR, -1);
+		setMidnight(calendar);
 		return calendar.getTime();
 	}
-	
+
 	/**
 	 * 格式化时间
 	 * @param date
 	 * @param pattern
 	 * @return
 	 */
-	public static String formatDate(Date date,String pattern){
+	public static String formatDate(Date date, String pattern) {
 		SimpleDateFormat format = new SimpleDateFormat(pattern);
 		return format.format(date);
 	}
-	
+
 	/**
 	 * 解析日期
 	 * @param source
@@ -428,8 +427,33 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
 	 * @return
 	 * @throws ParseException 
 	 */
-	public static Date parseDate(String source,String pattern) throws ParseException{
+	public static Date parseDate(String source, String pattern) throws ParseException {
 		SimpleDateFormat format = new SimpleDateFormat(pattern);
 		return format.parse(source);
 	}
+
+	/**
+	 * 时分秒毫秒归零
+	 * @param c
+	 * @return
+	 */
+	public static Calendar setMidnight(Calendar c) {
+		c.set(Calendar.HOUR_OF_DAY, 0);
+		c.set(Calendar.MINUTE, 0);
+		c.set(Calendar.SECOND, 0);
+		c.set(Calendar.MILLISECOND, 0);
+		return c;
+	}
+
+	/**
+	 * 时分秒毫秒归零
+	 * @param c
+	 * @return
+	 */
+	public static Date getEarlyToday() {
+		Calendar c = Calendar.getInstance();
+		setMidnight(c);
+		return c.getTime();
+	}
+
 }

+ 73 - 0
src/main/java/com/goafanti/report/bo/DepartmentSalesReportBO.java

@@ -0,0 +1,73 @@
+package com.goafanti.report.bo;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.goafanti.common.constant.AFTConstants;
+
+public class DepartmentSalesReportBO {
+	private String						id;
+	private String						superId;
+	private String						departmentName;
+	private String						managerName;
+	private int							memberCount;
+	private Map<String, SalesValues>	values;
+
+	public DepartmentSalesReportBO() {
+		this.values = new HashMap<>();
+		this.values.put(AFTConstants.DAILY, new SalesValues());
+		this.values.put(AFTConstants.WEEKLY, new SalesValues());
+		this.values.put(AFTConstants.MONTHLY, new SalesValues());
+		this.values.put(AFTConstants.QUARTERLY, new SalesValues());
+		this.values.put(AFTConstants.ANNUALLY, new SalesValues());
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getDepartmentName() {
+		return departmentName;
+	}
+
+	public void setDepartmentName(String departmentName) {
+		this.departmentName = departmentName;
+	}
+
+	public String getManagerName() {
+		return managerName;
+	}
+
+	public void setManagerName(String managerName) {
+		this.managerName = managerName;
+	}
+
+	public int getMemberCount() {
+		return memberCount;
+	}
+
+	public void setMemberCount(int memberCount) {
+		this.memberCount = memberCount;
+	}
+
+	public Map<String, SalesValues> getValues() {
+		return values;
+	}
+
+	public void setValues(Map<String, SalesValues> values) {
+		this.values = values;
+	}
+
+	public String getSuperId() {
+		return superId;
+	}
+
+	public void setSuperId(String superId) {
+		this.superId = superId;
+	}
+
+}

+ 75 - 0
src/main/java/com/goafanti/report/bo/PersonalSalesReportBO.java

@@ -0,0 +1,75 @@
+package com.goafanti.report.bo;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.goafanti.common.constant.AFTConstants;
+
+public class PersonalSalesReportBO {
+	private String						id;
+	private String						name;
+	private String						departmentName;
+	private String						position;
+	private Date						enrollTime;
+
+	private Map<String, SalesValues>	values;
+
+	public PersonalSalesReportBO() {
+		this.values = new HashMap<>();
+		this.values.put(AFTConstants.DAILY, new SalesValues());
+		this.values.put(AFTConstants.WEEKLY, new SalesValues());
+		this.values.put(AFTConstants.MONTHLY, new SalesValues());
+		this.values.put(AFTConstants.QUARTERLY, new SalesValues());
+		this.values.put(AFTConstants.ANNUALLY, new SalesValues());
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getDepartmentName() {
+		return departmentName;
+	}
+
+	public void setDepartmentName(String departmentName) {
+		this.departmentName = departmentName;
+	}
+
+	public String getPosition() {
+		return position;
+	}
+
+	public void setPosition(String position) {
+		this.position = position;
+	}
+
+	public Date getEnrollTime() {
+		return enrollTime;
+	}
+
+	public void setEnrollTime(Date enrollTime) {
+		this.enrollTime = enrollTime;
+	}
+
+	public Map<String, SalesValues> getValues() {
+		return values;
+	}
+
+	public void setValues(Map<String, SalesValues> values) {
+		this.values = values;
+	}
+
+}

+ 118 - 0
src/main/java/com/goafanti/report/bo/ReportDate.java

@@ -0,0 +1,118 @@
+package com.goafanti.report.bo;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import com.goafanti.common.utils.DateUtils;
+
+public class ReportDate {
+
+	private Date	dailyStart;
+	private Date	dailyEnd;
+	private Date	weeklyStart;
+	private Date	weeklyEnd;
+	private Date	monthStart;
+	private Date	monthEnd;
+	private Date	quarterStart;
+	private Date	quarterEnd;
+	private Date	yearStart;
+	private Date	yearEnd;
+
+	public ReportDate(Date startTime) {
+		Calendar start = DateUtils.setMidnight(new Calendar.Builder().setInstant(startTime).build());
+		this.dailyStart = start.getTime();
+		this.dailyEnd = DateUtils.addDays(start.getTime(), 1);
+		this.weeklyStart = DateUtils.getFirstDayOfWeek(startTime);
+		this.weeklyEnd = DateUtils.addDays(DateUtils.getLastDayOfWeek(startTime), 1);
+		this.monthStart = DateUtils.getFirstDayOfMonth(start.get(Calendar.YEAR), start.get(Calendar.MONTH));
+		this.monthEnd = DateUtils
+				.addDays(DateUtils.getLastDayOfMonth(start.get(Calendar.YEAR), start.get(Calendar.MONTH)), 1);
+		this.quarterStart = DateUtils.getFirstDayOfQuarter(startTime);
+		this.quarterEnd = DateUtils.addDays(DateUtils.getLastDayOfQuarter(startTime), 1);
+		this.yearStart = DateUtils.setMidnight(new Calendar.Builder().setDate(start.get(Calendar.YEAR), 0, 1).build())
+				.getTime();
+		this.yearEnd = DateUtils.setMidnight(new Calendar.Builder().setDate(start.get(Calendar.YEAR) + 1, 0, 1).build())
+				.getTime();
+	}
+
+	public Date getDailyStart() {
+		return dailyStart;
+	}
+
+	public void setDailyStart(Date dailyStart) {
+		this.dailyStart = dailyStart;
+	}
+
+	public Date getDailyEnd() {
+		return dailyEnd;
+	}
+
+	public void setDailyEnd(Date dailyEnd) {
+		this.dailyEnd = dailyEnd;
+	}
+
+	public Date getWeeklyStart() {
+		return weeklyStart;
+	}
+
+	public void setWeeklyStart(Date weeklyStart) {
+		this.weeklyStart = weeklyStart;
+	}
+
+	public Date getWeeklyEnd() {
+		return weeklyEnd;
+	}
+
+	public void setWeeklyEnd(Date weeklyEnd) {
+		this.weeklyEnd = weeklyEnd;
+	}
+
+	public Date getMonthStart() {
+		return monthStart;
+	}
+
+	public void setMonthStart(Date monthStart) {
+		this.monthStart = monthStart;
+	}
+
+	public Date getMonthEnd() {
+		return monthEnd;
+	}
+
+	public void setMonthEnd(Date monthEnd) {
+		this.monthEnd = monthEnd;
+	}
+
+	public Date getQuarterStart() {
+		return quarterStart;
+	}
+
+	public void setQuarterStart(Date quarterStart) {
+		this.quarterStart = quarterStart;
+	}
+
+	public Date getQuarterEnd() {
+		return quarterEnd;
+	}
+
+	public void setQuarterEnd(Date quarterEnd) {
+		this.quarterEnd = quarterEnd;
+	}
+
+	public Date getYearStart() {
+		return yearStart;
+	}
+
+	public void setYearStart(Date yearStart) {
+		this.yearStart = yearStart;
+	}
+
+	public Date getYearEnd() {
+		return yearEnd;
+	}
+
+	public void setYearEnd(Date yearEnd) {
+		this.yearEnd = yearEnd;
+	}
+
+}

+ 25 - 0
src/main/java/com/goafanti/report/bo/SalesValues.java

@@ -0,0 +1,25 @@
+package com.goafanti.report.bo;
+
+import java.math.BigDecimal;
+
+public class SalesValues {
+	private int			orderCount	= 0;
+	private BigDecimal	orderAmount	= BigDecimal.ZERO;
+
+	public int getOrderCount() {
+		return orderCount;
+	}
+
+	public void setOrderCount(int orderCount) {
+		this.orderCount = orderCount;
+	}
+
+	public BigDecimal getOrderAmount() {
+		return orderAmount;
+	}
+
+	public void setOrderAmount(BigDecimal orderAmount) {
+		this.orderAmount = orderAmount;
+	}
+
+}

+ 70 - 0
src/main/java/com/goafanti/report/controller/ReportApiController.java

@@ -0,0 +1,70 @@
+package com.goafanti.report.controller;
+
+import java.util.Date;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.goafanti.common.bo.Result;
+import com.goafanti.common.constant.AFTConstants;
+import com.goafanti.common.controller.BaseApiController;
+import com.goafanti.common.utils.DateUtils;
+import com.goafanti.report.enums.OrderBy;
+import com.goafanti.report.enums.SalesReportOrderField;
+import com.goafanti.report.service.SalesReportServiceImpl;
+
+@RestController
+@RequestMapping(value = "/api/admin/report")
+public class ReportApiController extends BaseApiController {
+	@Autowired
+	SalesReportServiceImpl reportService;
+
+	@RequestMapping(value = "/sales/personal", method = RequestMethod.GET)
+	public Result personal(@RequestParam(required = false) String orderField,
+			@RequestParam(required = false) String order, @RequestParam(required = false) String pSize,
+			@RequestParam(required = false) String pNo, @RequestParam(required = false) String date,
+			@RequestParam(required = false) String depName, @RequestParam(required = false) String name,
+			@RequestParam(required = false) String position) {
+		Date startTime = null;
+		try {
+			startTime = StringUtils.isNotBlank(date) ? DateUtils.parseDate(date, AFTConstants.YYYYMMDDHHMMSS)
+					: new Date();
+		} catch (Exception e) {
+			startTime = new Date();
+		}
+		Integer pageSize = StringUtils.isBlank(pSize) ? null : handlePageSize(pSize);
+		Integer pageNo = StringUtils.isBlank(pNo) ? null : handlePageNo(pNo);
+		if (pageSize != null && pageNo != null) {
+			pageNo = (pageNo - 1) * pageSize;
+		}
+		return res().data(reportService.getPersonSalesReports(SalesReportOrderField.getField(orderField),
+				OrderBy.getField(order), pageSize, pageNo, startTime, depName, name, position));
+	}
+
+	@RequestMapping(value = "/sales/total", method = RequestMethod.GET)
+	public Result total(String date) {
+		Date startTime = null;
+		try {
+			startTime = DateUtils.parseDate(date, AFTConstants.YYYYMMDDHHMMSS);
+		} catch (Exception e) {
+			startTime = new Date();
+		}
+		return res().data(reportService.getReportTotal(startTime));
+	}
+
+	@RequestMapping(value = "/sales/department", method = RequestMethod.GET)
+	public Result department(String date) {
+		Date startTime = null;
+		try {
+			startTime = DateUtils.parseDate(date, AFTConstants.YYYYMMDDHHMMSS);
+		} catch (Exception e) {
+			startTime = new Date();
+		}
+		return res().data(reportService.getDepartmentSalesReports(startTime));
+	}
+
+}

+ 43 - 0
src/main/java/com/goafanti/report/enums/OrderBy.java

@@ -0,0 +1,43 @@
+package com.goafanti.report.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum OrderBy {
+	DESC("desc", "降序"), ASC("asc", "升序");
+
+	private OrderBy(String code, String desc) {
+		this.code = code;
+		this.desc = desc;
+	}
+
+	private static Map<String, OrderBy> status = new HashMap<String, OrderBy>();
+
+	static {
+		for (OrderBy value : OrderBy.values()) {
+			status.put(value.getCode(), value);
+		}
+	}
+
+	public static OrderBy getField(String code) {
+		if (containsType(code)) {
+			return status.get(code);
+		}
+		return DESC;
+	}
+
+	public static boolean containsType(String code) {
+		return status.containsKey(code);
+	}
+
+	private String	code;
+	private String	desc;
+
+	public String getCode() {
+		return code;
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+}

+ 72 - 0
src/main/java/com/goafanti/report/enums/SalesReportOrderField.java

@@ -0,0 +1,72 @@
+package com.goafanti.report.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum SalesReportOrderField {
+	DailyOrderCount("dailyOrderCount", "每日订单量"),
+	DailyOrderAmount("dailyOrderAmount", "每日订单金额"),
+	WeeklyOrderCount("weeklyOrderCount", "每周订单量"),
+	WeeklyOrderAmount("weeklyOrderAmount", "每周订单金额"),
+	MonthlyOrderCount("monthlyOrderCount", "每月订单量"),
+	MonthlyOrderAmount("monthlyOrderAmount", "每月订单金额"),
+	QuarterlyOrderCount("quarterlyOrderCount", "每季度订单量"),
+	QuarterlyOrderAmount("quarterlyOrderAmount", "每季度订单金额"),
+	AnnuallyOrderCount("annuallyOrderCount", "每年订单量"),
+	AnnuallyOrderAmount("annuallyOrderAmount", "每年订单金额");
+
+	private SalesReportOrderField(String code, String desc) {
+		this.code = code;
+		this.desc = desc;
+	}
+
+	private static Map<String, SalesReportOrderField> status = new HashMap<String, SalesReportOrderField>();
+
+	static {
+		for (SalesReportOrderField value : values()) {
+			status.put(value.getCode(), value);
+		}
+	}
+
+	public static SalesReportOrderField getField(String code) {
+		if (containsType(code)) {
+			return status.get(code);
+		}
+		return DailyOrderAmount;
+	}
+
+	public static boolean isDaily(SalesReportOrderField field) {
+		return field == DailyOrderAmount || field == DailyOrderCount;
+	}
+
+	public static boolean isWeekly(SalesReportOrderField field) {
+		return field == WeeklyOrderAmount || field == WeeklyOrderCount;
+	}
+
+	public static boolean isMonthly(SalesReportOrderField field) {
+		return field == MonthlyOrderAmount || field == MonthlyOrderCount;
+	}
+
+	public static boolean isQuarterly(SalesReportOrderField field) {
+		return field == QuarterlyOrderAmount || field == QuarterlyOrderCount;
+	}
+
+	public static boolean isAnnually(SalesReportOrderField field) {
+		return field == AnnuallyOrderAmount || field == AnnuallyOrderCount;
+	}
+
+	public static boolean containsType(String code) {
+		return status.containsKey(code);
+	}
+
+	private String	code;
+	private String	desc;
+
+	public String getCode() {
+		return code;
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+}

+ 179 - 0
src/main/java/com/goafanti/report/service/SalesReportServiceImpl.java

@@ -0,0 +1,179 @@
+package com.goafanti.report.service;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.ui.ModelMap;
+
+import com.goafanti.common.constant.AFTConstants;
+import com.goafanti.common.dao.DailySalesReportMapper;
+import com.goafanti.core.mybatis.BaseMybatisDao;
+import com.goafanti.report.bo.DepartmentSalesReportBO;
+import com.goafanti.report.bo.PersonalSalesReportBO;
+import com.goafanti.report.bo.ReportDate;
+import com.goafanti.report.bo.SalesValues;
+import com.goafanti.report.enums.OrderBy;
+import com.goafanti.report.enums.SalesReportOrderField;
+
+@Service
+public class SalesReportServiceImpl extends BaseMybatisDao<DailySalesReportMapper> {
+
+	@Autowired
+	DailySalesReportMapper salesReportMapper;
+
+	public int insertDailyReports(Date startTime, Date endTime) {
+		return salesReportMapper.insertSalesReports(startTime, endTime);
+	}
+
+	public ModelMap getReportTotal(Date startTime) {
+		ReportDate rd = new ReportDate(startTime);
+		ModelMap mm = new ModelMap();
+		putField(mm, "dailyTotalCount", "dailyTotalAmount", rd.getDailyStart(), rd.getDailyEnd());
+		putField(mm, "weeklyTotalCount", "weeklyTotalAmount", rd.getWeeklyStart(), rd.getWeeklyEnd());
+		putField(mm, "monthlyTotalCount", "monthlyTotalAmount", rd.getMonthStart(), rd.getMonthEnd());
+		putField(mm, "quarterlyTotalCount", "quarterlyTotalAmount", rd.getQuarterStart(), rd.getQuarterEnd());
+		putField(mm, "annuallyTotalCount", "annuallyTotalAmount", rd.getYearStart(), rd.getYearEnd());
+		return mm;
+	}
+
+	private void putField(ModelMap mm, String count, String amount, Date start, Date end) {
+		ModelMap res = salesReportMapper.selectTotalReports(start, end);
+		mm.put(count, res.get("totalCount"));
+		mm.put(amount, res.get("totalAmount"));
+	}
+
+	public List<PersonalSalesReportBO> getPersonSalesReports(SalesReportOrderField orderField, OrderBy order,
+			Integer pageSize, Integer pageNo, Date startTime, String depName, String name, String position) {
+		ReportDate rd = new ReportDate(startTime);
+		List<PersonalSalesReportBO> list = null;
+		switch (orderField) {
+		case DailyOrderAmount:
+		case DailyOrderCount:
+			list = salesReportMapper.selectSalesPersonalReports(rd.getDailyStart(), rd.getDailyEnd(), pageNo, pageSize,
+					orderField.getCode(), order.getCode(), SalesReportOrderField.DailyOrderCount.getCode(),
+					SalesReportOrderField.DailyOrderAmount.getCode(), depName, name, position);
+			break;
+		case WeeklyOrderCount:
+		case WeeklyOrderAmount:
+			list = salesReportMapper.selectSalesPersonalReports(rd.getWeeklyStart(), rd.getWeeklyEnd(), pageNo,
+					pageSize, orderField.getCode(), order.getCode(), SalesReportOrderField.WeeklyOrderCount.getCode(),
+					SalesReportOrderField.WeeklyOrderAmount.getCode(), depName, name, position);
+			break;
+		case MonthlyOrderCount:
+		case MonthlyOrderAmount:
+			list = salesReportMapper.selectSalesPersonalReports(rd.getMonthStart(), rd.getMonthEnd(), pageNo, pageSize,
+					orderField.getCode(), order.getCode(), SalesReportOrderField.MonthlyOrderCount.getCode(),
+					SalesReportOrderField.MonthlyOrderAmount.getCode(), depName, name, position);
+			break;
+		case QuarterlyOrderCount:
+		case QuarterlyOrderAmount:
+			list = salesReportMapper.selectSalesPersonalReports(rd.getQuarterStart(), rd.getQuarterEnd(), pageNo,
+					pageSize, orderField.getCode(), order.getCode(),
+					SalesReportOrderField.QuarterlyOrderCount.getCode(),
+					SalesReportOrderField.QuarterlyOrderAmount.getCode(), depName, name, position);
+			break;
+		case AnnuallyOrderCount:
+		case AnnuallyOrderAmount:
+			list = salesReportMapper.selectSalesPersonalReports(rd.getYearStart(), rd.getYearEnd(), pageNo, pageSize,
+					orderField.getCode(), order.getCode(), SalesReportOrderField.AnnuallyOrderCount.getCode(),
+					SalesReportOrderField.AnnuallyOrderAmount.getCode(), depName, name, position);
+			break;
+		}
+		Map<String, PersonalSalesReportBO> map = new HashMap<>();
+		List<String> ids = list.stream().map(item -> {
+			map.put(item.getId(), item);
+			return item.getId();
+		}).collect(Collectors.toList());
+
+		if (pageSize == null || pageNo == null) {
+			// 如果没有分页,则取其他统计数据时返回所有数据
+			ids = null;
+		}
+		getPersonalExtraInfo(map, ids, AFTConstants.DAILY, rd.getDailyStart(), rd.getDailyEnd());
+		getPersonalExtraInfo(map, ids, AFTConstants.WEEKLY, rd.getWeeklyStart(), rd.getWeeklyEnd());
+		getPersonalExtraInfo(map, ids, AFTConstants.MONTHLY, rd.getMonthStart(), rd.getMonthEnd());
+		getPersonalExtraInfo(map, ids, AFTConstants.QUARTERLY, rd.getQuarterStart(), rd.getQuarterEnd());
+		getPersonalExtraInfo(map, ids, AFTConstants.ANNUALLY, rd.getYearStart(), rd.getYearEnd());
+
+		return list;
+	}
+
+	private void getPersonalExtraInfo(Map<String, PersonalSalesReportBO> map, List<String> ids, String field,
+			Date start, Date end) {
+		List<ModelMap> mms = salesReportMapper.selectSalesPersonalExtraReports(start, end, ids);
+		for (ModelMap mm : mms) {
+			Optional<SalesValues> svo = Optional.ofNullable(map.get(mm.get("id"))).map(it -> it.getValues())
+					.map(it -> it.get(field));
+			if (svo.isPresent()) {
+				svo.get().setOrderAmount((BigDecimal) mm.get("order_amount"));
+				svo.get().setOrderCount(((BigDecimal) mm.get("order_count")).intValue());
+			}
+		}
+	}
+
+	public List<DepartmentSalesReportBO> getDepartmentSalesReports(Date startTime) {
+		ReportDate rd = new ReportDate(startTime);
+		List<DepartmentSalesReportBO> list = salesReportMapper.selectSalesDepartmentReports();
+		Map<String, DepartmentSalesReportBO> map = new HashMap<>();
+
+		for (DepartmentSalesReportBO dsr : list) {
+			map.put(dsr.getId(), dsr);
+		}
+
+		getDepartmentExtraInfo(map, AFTConstants.DAILY, rd.getDailyStart(), rd.getDailyEnd());
+		getDepartmentExtraInfo(map, AFTConstants.WEEKLY, rd.getWeeklyStart(), rd.getWeeklyEnd());
+		getDepartmentExtraInfo(map, AFTConstants.MONTHLY, rd.getMonthStart(), rd.getMonthEnd());
+		getDepartmentExtraInfo(map, AFTConstants.QUARTERLY, rd.getQuarterStart(), rd.getQuarterEnd());
+		getDepartmentExtraInfo(map, AFTConstants.ANNUALLY, rd.getYearStart(), rd.getYearEnd());
+
+		for (DepartmentSalesReportBO dsr : list) {
+			if (StringUtils.isNotBlank(dsr.getSuperId()) && !StringUtils.equals(dsr.getId(), dsr.getSuperId())) {
+				addToParent(map, dsr.getValues(), dsr.getSuperId(), 0);
+			}
+		}
+
+		return list;
+	}
+
+	/**
+	 * 递归给所有上级增加销售统计, 业务规定最多3级上级,递归设定超出5级递归直接退出
+	 */
+	private void addToParent(Map<String, DepartmentSalesReportBO> map, Map<String, SalesValues> values, String parentId,
+			int level) {
+		DepartmentSalesReportBO dsr = map.get(parentId);
+		if (dsr != null) {
+			Map<String, SalesValues> pValues = dsr.getValues();
+			for (String period : values.keySet()) {
+				SalesValues psv = pValues.get(period);
+				SalesValues sv = values.get(period);
+				psv.setOrderCount(psv.getOrderCount() + sv.getOrderCount());
+				psv.setOrderAmount(psv.getOrderAmount().add(sv.getOrderAmount()));
+			}
+			if (StringUtils.isNotBlank(dsr.getSuperId()) && !StringUtils.equals(dsr.getId(), dsr.getSuperId())
+					&& level < 5) {
+				addToParent(map, values, dsr.getSuperId(), ++level);
+			}
+		}
+	}
+
+	private void getDepartmentExtraInfo(Map<String, DepartmentSalesReportBO> map, String field, Date start, Date end) {
+		List<ModelMap> mms = salesReportMapper.selectSalesDepartmentExtraReports(start, end);
+		for (ModelMap mm : mms) {
+			Optional<SalesValues> svo = Optional.ofNullable(map.get(mm.get("id"))).map(it -> it.getValues())
+					.map(it -> it.get(field));
+			if (svo.isPresent()) {
+				svo.get().setOrderAmount((BigDecimal) mm.get("order_amount"));
+				svo.get().setOrderCount(((BigDecimal) mm.get("order_count")).intValue());
+			}
+		}
+	}
+
+}