Browse Source

客户统计

wanghui 8 years ago
parent
commit
a9956f6545

+ 4 - 4
src/main/java/com/goafanti/admin/controller/AdminUserCertifyApiController.java

@@ -153,10 +153,10 @@ public class AdminUserCertifyApiController extends CertifyApiController {
 				|| IdentityAuditStatus.UNPAID.getCode().equals(ui.getAuditStatus())) {
 			ui.setProcess(IdentityProcess.COMMITTED.getCode());
 		} else if (IdentityAuditStatus.PAID.getCode().equals(ui.getAuditStatus())) {
-			ui.setProcess(IdentityProcess.FILLIN.getCode());
+			ui.setProcess(IdentityProcess.FAIL.getCode());
 		} else if (IdentityAuditStatus.NOTPASSED.getCode().equals(ui.getAuditStatus())
 				|| IdentityAuditStatus.PASSED.getCode().equals(ui.getAuditStatus())) {
-			ui.setProcess(IdentityProcess.RESULTS.getCode());
+			ui.setProcess(IdentityProcess.SUCCESS.getCode());
 		}
 		res.setData(userIdentityService.updateUserDetailByAuditAdmin(ui, aid, mid, userIdentity.getLevel()));
 		return res;
@@ -234,10 +234,10 @@ public class AdminUserCertifyApiController extends CertifyApiController {
 				|| IdentityAuditStatus.UNPAID.getCode().equals(oi.getAuditStatus())) {
 			oi.setProcess(IdentityProcess.COMMITTED.getCode());
 		} else if (IdentityAuditStatus.PAID.getCode().equals(oi.getAuditStatus())) {
-			oi.setProcess(IdentityProcess.FILLIN.getCode());
+			oi.setProcess(IdentityProcess.FAIL.getCode());
 		} else if (IdentityAuditStatus.NOTPASSED.getCode().equals(oi.getAuditStatus())
 				|| IdentityAuditStatus.PASSED.getCode().equals(oi.getAuditStatus())){
-			oi.setProcess(IdentityProcess.RESULTS.getCode());
+			oi.setProcess(IdentityProcess.SUCCESS.getCode());
 		}
 		res.setData(organizationIdentityService.updateOrgDetailByAuditAdmin(oi, aid, mid, orgIdentity.getLevel()));
 		return res;

+ 8 - 18
src/main/java/com/goafanti/common/constant/AFTConstants.java

@@ -59,31 +59,21 @@ public class AFTConstants {
 
 	public static final Integer	INTERNATIONAL_ORG_CACHE_KEY			= 672;
 
-	public static final String	YES									= "1";
+	public static final Integer	YES									= 1;
 	
-	public static final String CUSTOMER_CREATE						= "创建客户";
-	
-	public static final String CUSTOMER_DELETE						= "删除客户";
-	
-	public static final String CUSTOMER_TRANSFER					= "转交客户";
-	
-	public static final String CUSTOMER_MODIFY						= "修改客户资料";
-	
-	public static final String CUSTOMER_RECEIVE                     = "领取客户";
-	
-	public static final String CUSTOMER_TO_PUBLIC					= "转为公共客户";
-	
-	public static final String CUSTOMER_FOLLOW						= "跟进客户";
-	
-	public static final String CUSTOMER_VIEW_ALL					= "customer_view_all";
+	public static final Integer  NO									= 0;
 	
 	public static final String USER_TYPE_PERSONAL					= "0";
 	
 	public static final String USER_TYPE_ORGANIZATION				= "1";
 	
-	public static final Integer SHARE_TYPE_PRIVATE					= 0;
+	public static final Integer USER_SOURCE_REGISTER				= 0;
+	
+	public static final Integer USER_SOURCE_CREATE					= 1;
+	
+	public static final Integer USER_SHARE_PRIVATE					= 0;
 	
-	public static final Integer SHARE_TYPE_PUBLIC					= 1;
+	public static final Integer USER_SHARE_PUBLIC					= 1;
 	
 	public static final Integer USER_STATUS_NORMAL					= 0;
 	

+ 10 - 3
src/main/java/com/goafanti/common/dao/UserMapper.java

@@ -17,6 +17,7 @@ import com.goafanti.customer.bo.CustomerOrganizationDetailBo;
 import com.goafanti.customer.bo.CustomerPersonalDetailBo;
 import com.goafanti.customer.bo.CustomerSimpleBo;
 import com.goafanti.customer.bo.FollowBusinessBo;
+import com.goafanti.customer.bo.StatisticBo;
 
 public interface UserMapper {
 	/**
@@ -142,7 +143,7 @@ public interface UserMapper {
 	User findUserAccountDetail(@Param("uid")String uid);
 
 	/**
-	 * 查看客户联系人列�?
+	 * 查看客户联系人列�?
 	 * @param uid
 	 * @return
 	 */
@@ -156,14 +157,14 @@ public interface UserMapper {
 	FollowBusinessBo findFollowById(String followId);
 
 	/**
-	 * 查询单次拜访推进的客户业�?
+	 * 查询单次拜访推进的客户业�?
 	 * @param followId
 	 * @return
 	 */
 	List<UserBusiness> findBusinessByFollowId(String followId);
 
 	/**
-	 * 查询客户�?有联系人
+	 * 查询客户�?有联系人
 	 * @param uid
 	 * @return
 	 */
@@ -177,5 +178,11 @@ public interface UserMapper {
 	 * @return
 	 */
 	List<User> checkUser(@Param("id")String id,@Param("identifyName")String identifyName, @Param("mobile")String mobile,@Param("type")Integer type);
+	
+	/**
+	 * 查询一个营销员的拜访数量 和客户数量
+	 * @param aid
+	 */
+	StatisticBo selectFollowAndCustomerCount(@Param("aid")String aid);
 
 }

+ 6 - 4
src/main/java/com/goafanti/common/enums/IdentityProcess.java

@@ -7,10 +7,12 @@ import org.apache.commons.lang3.StringUtils;
 
 public enum IdentityProcess {
 	
-	UNCOMMITTED(0, "填写认证信息"),
-	COMMITTED(3, "审核信息"),
-	FILLIN(4, "填写银行卡金额"),
-	RESULTS(5, "认证结果"),
+	UNCOMMITTED(0, "未提交审核"),
+	COMMITTED(1, "提交审核"),
+	UNPAY(2, "审核未打款"),
+	PAY(3, "审核已打款"),
+	FAIL(4, "审核未通过"),
+	SUCCESS(5, "审核通过"),
 	OTHER(6, "其他");
 
 	private IdentityProcess(Integer code, String desc) {

+ 47 - 0
src/main/java/com/goafanti/common/enums/MemberStatus.java

@@ -0,0 +1,47 @@
+package com.goafanti.common.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum MemberStatus{
+	OTHER(null,"No This Filed"),
+	NORMAL(0,"正常"),
+	LOCK(1,"锁定"),
+	OVERDUE(2,"过期");
+	private MemberStatus(Integer code, String desc) {
+		this.code = code;
+		this.desc = desc;
+	}
+	
+	private static Map<Integer, MemberStatus> status = new HashMap<Integer, MemberStatus>();
+
+	static {
+		for (MemberStatus value : MemberStatus.values()) {
+			status.put(value.getCode(), value);
+		}
+	}
+	
+	public static MemberStatus getField(String code) {
+		if (containsType(code)) {
+			return status.get(code);
+		}
+		return OTHER;
+	}
+	
+	public static String getFieldDesc(String code) {
+		return getField(code).getDesc();
+	}
+
+	public static boolean containsType(String code) {
+		return status.containsKey(code);
+	}
+	private Integer	code;
+	private String	desc;
+
+	public Integer getCode() {
+		return code;
+	}
+	public String getDesc() {
+		return desc;
+	}
+}

+ 14 - 3
src/main/java/com/goafanti/common/mapper/AdminMapper.xml

@@ -13,10 +13,11 @@
     <result column="position" property="position" jdbcType="VARCHAR" />
     <result column="superior_id" property="superiorId" jdbcType="VARCHAR" />
     <result column="city" property="city" jdbcType="INTEGER" />
+    <result column="department_id" property="departmentId" jdbcType="VARCHAR"/>
   </resultMap>
   <sql id="Base_Column_List" >
     id, mobile, name, password, email, create_time, number, province, position, superior_id,
-    city
+    city,department_id
   </sql>
   <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String" >
     select 
@@ -35,7 +36,7 @@
     values (#{id,jdbcType=VARCHAR}, #{mobile,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, 
       #{password,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, 
       #{number,jdbcType=INTEGER}, #{province,jdbcType=INTEGER}, #{position,jdbcType=VARCHAR},
-      #{superiorId,jdbcType=VARCHAR}, #{city,jdbcType=INTEGER}
+      #{superiorId,jdbcType=VARCHAR}, #{city,jdbcType=INTEGER},#{departmentId,jdbcType=VARCHAR}
       )
   </insert>
   <insert id="insertSelective" parameterType="com.goafanti.common.model.Admin" >
@@ -74,6 +75,9 @@
       <if test="city != null" >
         city,
       </if>
+      <if test="departmentId != null">
+      	department_id,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides="," >
       <if test="id != null" >
@@ -109,6 +113,9 @@
       <if test="city != null" >
         #{city,jdbcType=INTEGER},
       </if>
+     <if test="departmentId != null">
+     	#{departmentId,jdbcType=VARCHAR},
+     </if>
     </trim>
   </insert>
   <update id="updateByPrimaryKeySelective" parameterType="com.goafanti.common.model.Admin" >
@@ -144,6 +151,9 @@
        <if test="city != null" >
         city = #{city,jdbcType=INTEGER},
       </if>
+      <if test="departmentId != null">
+     	department_id = #{departmentId,jdbcType=VARCHAR},
+      </if>
     </set>
     where id = #{id,jdbcType=VARCHAR}
   </update>
@@ -158,7 +168,8 @@
       province = #{province,jdbcType=INTEGER},
       position = #{position,jdbcType=VARCHAR},
       superior_id = #{superiorId,jdbcType=VARCHAR},
-      city = #{city,jdbcType=INTEGER}
+      city = #{city,jdbcType=INTEGER},
+      department_id = #{departmentId,jdbcType=VARCHAR},
     where id = #{id,jdbcType=VARCHAR}
   </update>
   

+ 207 - 5
src/main/java/com/goafanti/common/mapper/UserMapperExt.xml

@@ -8,6 +8,7 @@
 			a.status, 
 			date_format(a.create_time,'%Y-%m-%d %H:%i:%s') as createTime,
 			a.business_audit as businessAudit,
+			a.current_member_status as currentMemberStatus,
 			a.identify_name as name,
 			a.lvl,a.is_member as isMember,
 			a.society_tag as societyTag,
@@ -28,7 +29,7 @@
 			type,
 			status,
 			create_time,
-			businessAudit,
+			business_audit,
 			current_member_status,
 			identify_name,
 			lvl,
@@ -361,6 +362,7 @@
 			a.company_logo_url as companyLogoUrl,
 			a.introduction,
 		    a.identify_name as identifyName,
+		    a.business_audit as businessAudit,
 			b.industry,
 			b.location_province as locationProvince,
 			b.location_city as locationCity,
@@ -383,14 +385,16 @@
 			b.id,
 			b.contacts,
 			b.contact_mobile as contactMobile,
-			b.investment
+			b.investment,
+			b.audit_status as auditStatus
 		from 
 		(select 
 			id,
 			identify_name,
 			society_tag,
 			company_logo_url,
-			introduction
+			introduction,
+			business_audit
 		from 
 			user
 		where 
@@ -405,6 +409,7 @@
 			a.society_tag as societyTag,
 			a.head_portrait_url as headPortraitUrl,
 			a.introduction,
+			a.business_audit as businessAudit,
 			b.id,
 			b.industry,
 			b.sex,
@@ -431,7 +436,8 @@
 			b.education,
 			b.major_category as majorCategory,
 			b.qualification,
-			b.investment
+			b.investment,
+			b.audit_status as auditStatus
 		from
 			(
 				select
@@ -439,7 +445,8 @@
 					identify_name,
 					society_tag,
 					head_portrait_url,
-					introduction
+					introduction,
+					business_audit
 				from
 					user
 				where
@@ -554,6 +561,201 @@
 		where a.id = #{followId,jdbcType=VARCHAR}
 	</select>
 
+	<select id="customerStatisticsList" resultType="com.goafanti.customer.bo.StatisticBo">
+		select a.*,b.name as adminName,c.name as departmentName from (
+			select 
+			aid,
+			sum(case when customer_status = 0 then 1 else 0 end) as newNo, <!-- 新客户 -->
+			sum(case when customer_status = 1 then 1 else 0 end) as intentionNo, <!-- 意向客户 -->
+			sum(case when customer_status = 2 then 1 else 0 end) as pointNo,  <!-- 重点客户 -->
+			sum(case when customer_status = 3 then 1 else 0 end) as interviewNo, <!-- 面谈客户 -->
+			sum(case when customer_status = 4 then 1 else 0 end) as signNo, <!-- 签单客户 -->
+			sum(case when customer_status = 5 then 1 else 0 end) as refuseNo, <!-- 拒绝客户 -->
+			sum(case when customer_status = 6 then 1 else 0 end) as stopNo <!-- 停止跟进 -->
+			from user_business where 1=1
+				<if test="sDate != null">
+				 	and create_time &gt; #{sDate,jdbcType=DATE}
+				</if>
+				<if test="eDate != null">
+				 	and create_time &lt; #{eDate,jdbcType=DATE}
+				</if>
+				<if test="businessGlossoryId != null">
+					and business_glossory_id = #{businessGlossoryId,jdbcType=VARCHAR}
+				</if>
+			group by aid
+			)a 
+		left join admin b on a.aid = b.id 
+		left join department_management c on b.department_id = c.id
+		<if test="departmentId !=null">
+			where b.department_id = #{departmentId,jdbcType=VARCHAR}
+		</if>
+		<if test="page_sql != null">
+    		${page_sql}
+   		 </if>
+	</select>
+
+	<select id="customerStatisticsCount" resultType="java.lang.Integer">
+		select count(0) from (
+			select 
+			aid
+			from user_business where 1=1
+			<if test="sDate != null">
+				 and create_time &gt; #{sDate,jdbcType=DATE}
+			</if>
+			<if test="eDate != null">
+				and create_time &lt; #{eDate,jdbcType=DATE}
+			</if>
+			<if test="businessGlossoryId != null">
+				and business_glossory_id = #{businessGlossoryId,jdbcType=VARCHAR}
+			</if>
+			group by aid
+		)a
+		left join admin b on a.aid = b.id 
+		left join department_management c on b.department_id = c.id
+		<if test="departmentId !=null">
+			where b.department_id = #{departmentId,jdbcType=VARCHAR}
+		</if>
+	</select>
+	
+	<select id="businessStatisticList" resultType="com.goafanti.customer.bo.StatisticBo">
+		select a.*,b.name as adminName,c.name as departmentName from (
+			select
+			aid,
+			sum(case when follow_situation = 0 then 1 else 0 end) as sendMaterialNo, <!-- 已发项目介绍资料 -->
+			sum(case when follow_situation = 1 then 1 else 0 end) as interviewNo, <!-- 已约面谈 -->
+			sum(case when follow_situation = 2 then 1 else 0 end) as sendProspectusNo, <!-- 已发合同计划书 -->
+			sum(case when follow_situation = 3 then 1 else 0 end) as quoteNo, <!-- 已报价 -->
+			sum(case when follow_situation = 4 then 1 else 0 end) as sendContractNo, <!-- 已发合同 -->
+			sum(case when follow_situation = 5 then 1 else 0 end) as signContractNo, <!-- 已签合同 -->
+			sum(case when follow_situation = 6 then 1 else 0 end) as onVisaNo, <!-- 面谈中 -->
+			sum(case when follow_situation = 7 then 1 else 0 end) as visaNo <!-- 已面签 -->
+			from user_business where 1=1
+			<if test="sDate != null">
+				 and create_time &gt; #{sDate,jdbcType=DATE}
+			</if>
+			<if test="eDate != null">
+				and create_time &lt; #{eDate,jdbcType=DATE}
+			</if>
+			<if test="businessGlossoryId != null">
+				and business_glossory_id = #{businessGlossoryId,jdbcType=VARCHAR}
+			</if>
+			group by aid
+			)a
+			left join admin b on a.aid = b.id 
+			left join department_management c on b.department_id = c.id
+		<if test="departmentId !=null">
+			where b.department_id = #{departmentId,jdbcType=VARCHAR}
+		</if>
+		<if test="page_sql != null">
+    		${page_sql}
+   		 </if>
+	</select>
+	
+	<select id="businessStatisticCount" resultType="java.lang.Integer">
+		select count(0) from (
+			select
+			aid
+			from user_business where 1=1
+			<if test="sDate != null">
+				 and create_time &gt; #{sDate,jdbcType=DATE}
+			</if>
+			<if test="eDate != null">
+				and create_time &lt; #{eDate,jdbcType=DATE}
+			</if>
+			<if test="businessGlossoryId != null">
+				and business_glossory_id = #{businessGlossoryId,jdbcType=VARCHAR}
+			</if>
+			group by aid
+			)a
+			left join admin b on a.aid = b.id 
+			left join department_management c on b.department_id = c.id
+		<if test="departmentId !=null">
+			where b.department_id = #{departmentId,jdbcType=VARCHAR}
+		</if>
+	</select>
+	
+	<select id="followStatisticList" resultType="com.goafanti.customer.bo.StatisticBo">
+		select a.*,b.name as adminName,c.name as departmentName from (
+		select
+			aid,
+			sum(case when contact_type = 0 then 1 else 0 end) as visitNo, <!-- 外出 -->
+			sum(case when contact_type = 1 then 1 else 0 end) as telNo, <!-- 电话 -->
+			sum(case when contact_type = 2 then 1 else 0 end) as qqNo, <!-- QQ -->
+			sum(case when contact_type = 3 then 1 else 0 end) as wxNo, <!-- 微信 -->
+			sum(case when contact_type = 4 then 1 else 0 end) as emailNo, <!-- 邮件 -->
+			sum(case when contact_type = 5 then 1 else 0 end) as letterNo <!-- 书信 -->
+			from user_follow where 1=1 
+			<if test="sDate != null">
+				and create_time &gt; #{sDate,jdbcType=DATE}
+			</if>
+			<if test="eDate != null">
+				and create_time &lt; #{eDate,jdbcType=DATE}
+			</if>
+			group by aid
+		)a
+		left join admin b on a.aid = b.id 
+		left join department_management c on b.department_id = c.id
+		<if test="departmentId !=null">
+			where b.department_id = #{departmentId,jdbcType=VARCHAR}
+		</if>
+	</select>
+	
+	<select id="followStatisticCount" resultType="java.lang.Integer">
+		select count(0) from (
+		select
+			aid
+			from user_follow where 1=1 
+			<if test="sDate != null">
+				and create_time &gt; #{sDate,jdbcType=DATE}
+			</if>
+			<if test="sDate != null">
+				and create_time &lt; #{eDate,jdbcType=DATE}
+			</if>
+			group by aid
+		)a
+		left join admin b on a.aid = b.id 
+		left join department_management c on b.department_id = c.id
+		<if test="departmentId !=null">
+			where b.department_id = #{departmentId,jdbcType=VARCHAR}
+		</if>
+	</select>
+	
+	<select id="selectFollowAndCustomerCount" parameterType="java.lang.String" resultType="com.goafanti.customer.bo.StatisticBo">
+		select
+			x.customerNo,
+			y.followNo
+		from
+			(
+				select
+					count( 0 ) as customerNo,
+					a.aid
+				from
+					(
+						select
+							aid,
+							uid
+						from
+							user_follow
+						where
+							aid = #{aid,jdbcType=VARCHAR}
+						group by
+							aid,
+							uid
+					) a
+				group by
+					a.aid
+			) x left join(
+				select
+					count( 0 ) as followNo,
+					aid
+				from
+					user_follow
+				where
+					aid = #{aid,jdbcType=VARCHAR}
+			) y on
+			x.aid = y.aid;
+	</select>
+	
 	<select id="findBusinessByFollowId" parameterType="java.lang.String" resultType="com.goafanti.common.model.UserBusiness">
 		select
 		a.id,

+ 13 - 0
src/main/java/com/goafanti/common/model/Admin.java

@@ -61,6 +61,11 @@ public class Admin extends BaseModel implements AftUser {
 	 */
 	private Integer				city;
 	
+	/**
+	 * 部门管理
+	 */
+	private String 				departmentId;
+	
 	public String getSuperiorId() {
 		return superiorId;
 	}
@@ -152,6 +157,14 @@ public class Admin extends BaseModel implements AftUser {
 		this.city = city;
 	}
 
+	public String getDepartmentId() {
+		return departmentId;
+	}
+
+	public void setDepartmentId(String departmentId) {
+		this.departmentId = departmentId;
+	}
+
 	// 创建时间
 	public String getCreateTimeFormattedDate() {
 		if (this.createTime == null) {

+ 1 - 1
src/main/java/com/goafanti/common/model/User.java

@@ -2,7 +2,7 @@ package com.goafanti.common.model;
 
 import java.util.Date;
 
-public class User implements AftUser{
+public class  User extends BaseModel implements AftUser{
     /**
 	 * This field was generated by MyBatis Generator. This field corresponds to the database column user.id
 	 * @mbg.generated  Thu Nov 30 16:41:39 CST 2017

+ 335 - 0
src/main/java/com/goafanti/common/utils/DateUtils.java

@@ -4,7 +4,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";
+	
 	/**
 	 * Determines how two dates compare up to no more than the specified most
 	 * significant field.
@@ -71,5 +81,330 @@ 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
+     */
+	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){
+		Calendar calendar = Calendar.getInstance();
+		calendar.set(Calendar.YEAR, year - 1);
+		calendar.roll(Calendar.DAY_OF_YEAR, -1);
+		return calendar.getTime();
+	}
 }

+ 7 - 0
src/main/java/com/goafanti/customer/bo/CustomerOrganizationDetailBo.java

@@ -7,6 +7,7 @@ public class CustomerOrganizationDetailBo extends OrganizationIdentity{
 	private String societyTag;
 	private String companyLogoUrl;
 	private String introduction;
+	private Integer businessAudit;
 	public String getIdentifyName() {
 		return identifyName;
 	}
@@ -31,4 +32,10 @@ public class CustomerOrganizationDetailBo extends OrganizationIdentity{
 	public void setIntroduction(String introduction) {
 		this.introduction = introduction;
 	}
+	public Integer getBusinessAudit() {
+		return businessAudit;
+	}
+	public void setBusinessAudit(Integer businessAudit) {
+		this.businessAudit = businessAudit;
+	}
 }

+ 7 - 0
src/main/java/com/goafanti/customer/bo/CustomerPersonalDetailBo.java

@@ -7,6 +7,7 @@ public class CustomerPersonalDetailBo extends UserIdentity{
 	private String societyTag;
 	private String headPortraitUrl;
 	private String introduction;
+	private Integer businessAudit;
 	public String getIdentifyName() {
 		return identifyName;
 	}
@@ -31,4 +32,10 @@ public class CustomerPersonalDetailBo extends UserIdentity{
 	public void setIntroduction(String introduction) {
 		this.introduction = introduction;
 	}
+	public Integer getBusinessAudit() {
+		return businessAudit;
+	}
+	public void setBusinessAudit(Integer businessAudit) {
+		this.businessAudit = businessAudit;
+	}
 }

+ 206 - 0
src/main/java/com/goafanti/customer/bo/StatisticBo.java

@@ -0,0 +1,206 @@
+package com.goafanti.customer.bo;
+
+public class StatisticBo {
+	/** 营销员ID **/
+	private String aid;
+	/** 营销员姓名 **/
+	private String adminName;
+	/** 部门名称 **/
+	private String departmentName;
+	/** 拜访次数 **/
+	private String followNo;
+	/** 客户数量 **/
+	private String customerNo;
+	/** 电话数量 **/
+	private String telNo;
+	/** QQ数量 **/
+	private String qqNo;
+	/** 拜访量 **/
+	private String visitNo;
+	/** 邮件量 **/
+	private String emailNo;
+	/** 书信量 **/
+	private String letterNo;
+	/** 微信 **/
+	private String wxNo;
+	/** 新客户 **/
+	private String newNo;
+	/** 意向客户 **/
+	private String intentionNo;
+	/** 重点客户 **/
+	private String pointNo;
+	/** 面谈客户 **/
+	private String interviewNo;
+	/** 签订客户 **/
+	private String signNo;
+	/** 拒绝客户 **/
+	private String refuseNo;
+	/** 停止跟进 **/
+	private String stopNo;
+	
+	/** 发送资料 **/
+	private String sendMaterialNo;
+	/** 发送计划书 **/
+	private String sendProspectusNo;
+	/** 已经报价 **/
+	private String quoteNo;
+	/** 已发合同 **/
+	private String sendContractNo;
+	/** 已签合同 **/
+	private String signContractNo;
+	/** 面谈中 **/
+	private String onVisaNo;
+	/** 已面签 **/
+	private String visaNo;
+	
+	public String getAid() {
+		return aid;
+	}
+	public void setAid(String aid) {
+		this.aid = aid;
+	}
+	public String getAdminName() {
+		return adminName;
+	}
+	public void setAdminName(String adminName) {
+		this.adminName = adminName;
+	}
+	public String getDepartmentName() {
+		return departmentName;
+	}
+	public void setDepartmentName(String departmentName) {
+		this.departmentName = departmentName;
+	}
+	public String getFollowNo() {
+		return followNo;
+	}
+	public void setFollowNo(String followNo) {
+		this.followNo = followNo;
+	}
+	public String getCustomerNo() {
+		return customerNo;
+	}
+	public void setCustomerNo(String customerNo) {
+		this.customerNo = customerNo;
+	}
+	public String getTelNo() {
+		return telNo;
+	}
+	public void setTelNo(String telNo) {
+		this.telNo = telNo;
+	}
+	public String getQqNo() {
+		return qqNo;
+	}
+	public void setQqNo(String qqNo) {
+		this.qqNo = qqNo;
+	}
+	public String getVisitNo() {
+		return visitNo;
+	}
+	public void setVisitNo(String visitNo) {
+		this.visitNo = visitNo;
+	}
+	public String getEmailNo() {
+		return emailNo;
+	}
+	public void setEmailNo(String emailNo) {
+		this.emailNo = emailNo;
+	}
+	public String getLetterNo() {
+		return letterNo;
+	}
+	public void setLetterNo(String letterNo) {
+		this.letterNo = letterNo;
+	}
+	public String getWxNo() {
+		return wxNo;
+	}
+	public void setWxNo(String wxNo) {
+		this.wxNo = wxNo;
+	}
+	public String getNewNo() {
+		return newNo;
+	}
+	public void setNewNo(String newNo) {
+		this.newNo = newNo;
+	}
+	public String getIntentionNo() {
+		return intentionNo;
+	}
+	public void setIntentionNo(String intentionNo) {
+		this.intentionNo = intentionNo;
+	}
+	public String getPointNo() {
+		return pointNo;
+	}
+	public void setPointNo(String pointNo) {
+		this.pointNo = pointNo;
+	}
+	public String getInterviewNo() {
+		return interviewNo;
+	}
+	public void setInterviewNo(String interviewNo) {
+		this.interviewNo = interviewNo;
+	}
+	public String getSignNo() {
+		return signNo;
+	}
+	public void setSignNo(String signNo) {
+		this.signNo = signNo;
+	}
+	public String getRefuseNo() {
+		return refuseNo;
+	}
+	public void setRefuseNo(String refuseNo) {
+		this.refuseNo = refuseNo;
+	}
+	public String getStopNo() {
+		return stopNo;
+	}
+	public void setStopNo(String stopNo) {
+		this.stopNo = stopNo;
+	}
+	public String getSendMaterialNo() {
+		return sendMaterialNo;
+	}
+	public void setSendMaterialNo(String sendMaterialNo) {
+		this.sendMaterialNo = sendMaterialNo;
+	}
+	public String getSendProspectusNo() {
+		return sendProspectusNo;
+	}
+	public void setSendProspectusNo(String sendProspectusNo) {
+		this.sendProspectusNo = sendProspectusNo;
+	}
+	public String getQuoteNo() {
+		return quoteNo;
+	}
+	public void setQuoteNo(String quoteNo) {
+		this.quoteNo = quoteNo;
+	}
+	public String getSendContractNo() {
+		return sendContractNo;
+	}
+	public void setSendContractNo(String sendContractNo) {
+		this.sendContractNo = sendContractNo;
+	}
+	public String getSignContractNo() {
+		return signContractNo;
+	}
+	public void setSignContractNo(String signContractNo) {
+		this.signContractNo = signContractNo;
+	}
+	public String getOnVisaNo() {
+		return onVisaNo;
+	}
+	public void setOnVisaNo(String onVisaNo) {
+		this.onVisaNo = onVisaNo;
+	}
+	public String getVisaNo() {
+		return visaNo;
+	}
+	public void setVisaNo(String visaNo) {
+		this.visaNo = visaNo;
+	}
+}

+ 129 - 0
src/main/java/com/goafanti/customer/controller/CustomerApiController.java

@@ -2,6 +2,7 @@ package com.goafanti.customer.controller;
 
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
+import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -33,6 +34,7 @@ import com.goafanti.common.model.OrganizationContactBook;
 import com.goafanti.common.model.User;
 import com.goafanti.common.model.UserBusiness;
 import com.goafanti.common.utils.BeanUtilsExt;
+import com.goafanti.common.utils.DateUtils;
 import com.goafanti.common.utils.ExcelUtils;
 import com.goafanti.common.utils.StringUtils;
 import com.goafanti.core.shiro.token.TokenManager;
@@ -461,4 +463,131 @@ public class CustomerApiController extends BaseApiController{
 		customerService.updateByOperatorType(uid, AFTConstants.USER_TRANSFER_TO_PUBLIC);
 		return res;
 	}
+	
+	/** 图片上传 **/
+	@RequestMapping(value = "/uploadCustomerImg", method = RequestMethod.POST)
+	public Result uploadCustomerImg(HttpServletRequest req,String sign){
+		Result res = new Result();
+		res.setData(handleFile(res, "/customer_sys_file/", false, req, sign));
+		return res;
+	}
+	
+	/**
+	 * 
+	 * @param startDate 开始日期
+	 * @param endDate 结束日期
+	 * @param timeSpan 时间差
+	 * @param depId 部门编号
+	 * @param pageNo 页码
+	 * @param pageSize 页数
+	 * @return
+	 * @throws ParseException
+	 */
+	@SuppressWarnings("static-access")
+	@RequestMapping(value = "/customerStatistics",method = RequestMethod.GET)
+	public Result customerStatistics(String startDate,String endDate,String timeSpan,String depId,Integer pageNo, Integer pageSize) throws ParseException{
+		Result res = new Result();
+		Date sDate = null;
+		Date eDate = null;
+		DateUtils dateUtils = new DateUtils();
+		DateFormat format = new SimpleDateFormat(AFTConstants.YYYYMMDD);
+		if(StringUtils.isNotBlank(startDate)) sDate = format.parse(startDate);
+		if(StringUtils.isNotBlank(endDate)) eDate = format.parse(endDate);
+		if(StringUtils.isBlank(startDate)&&StringUtils.isBlank(endDate)){
+			Date date = new Date();
+			if(timeSpan.equals(DateUtils.DAY_SPAN)){
+				sDate = dateUtils.getYesterday();
+			}else if(timeSpan.equals(DateUtils.WEEK_SPAN)){
+				sDate = dateUtils.getLastDayOfLastWeek(date);
+			}else if(timeSpan.equals(DateUtils.MONTH_SPAN)){
+				sDate = dateUtils.getLastDayOfLastMonth(date);
+			}else if(timeSpan.equals(DateUtils.QUARTER_SPAN)){
+				sDate = dateUtils.getLastDayOfLastQuarter(date);
+			}else if(timeSpan.equals(DateUtils.YEAR_SPAN)){
+				sDate = dateUtils.getLastDayOfLastYear(date);
+			}		
+		}
+		res.setData(customerService.customerStatistics(sDate,eDate,depId,pageNo,pageSize));
+		return res;
+	}
+	
+	/**
+	 * 
+	 * @param startDate 开始日期
+	 * @param endDate 结束日期
+	 * @param timeSpan 时间差
+	 * @param depId 部门编号
+	 * @param businessGlossoryId 业务编号
+	 * @param pageNo 页码
+	 * @param pageSiz 页数
+	 * @return
+	 * @throws ParseException 
+	 */
+	@SuppressWarnings("static-access")
+	@RequestMapping(value = "/businessStatistic", method = RequestMethod.GET)
+	public Result businessStatistic(String startDate,String endDate,String timeSpan,String depId,String businessGlossoryId,Integer pageNo, Integer pageSize) throws ParseException{
+		Result res = new Result();
+		Date sDate = null;
+		Date eDate = null;
+		DateUtils dateUtils = new DateUtils();
+		DateFormat format = new SimpleDateFormat(AFTConstants.YYYYMMDD);
+		if(StringUtils.isNotBlank(startDate)) sDate = format.parse(startDate);
+		if(StringUtils.isNotBlank(endDate)) eDate = format.parse(endDate);
+		if(StringUtils.isBlank(startDate)&&StringUtils.isBlank(endDate)){
+			Date date = new Date();
+			if(timeSpan.equals(DateUtils.DAY_SPAN)){
+				sDate = dateUtils.getYesterday();
+			}else if(timeSpan.equals(DateUtils.WEEK_SPAN)){
+				sDate = dateUtils.getLastDayOfLastWeek(date);
+			}else if(timeSpan.equals(DateUtils.MONTH_SPAN)){
+				sDate = dateUtils.getLastDayOfLastMonth(date);
+			}else if(timeSpan.equals(DateUtils.QUARTER_SPAN)){
+				sDate = dateUtils.getLastDayOfLastQuarter(date);
+			}else if(timeSpan.equals(DateUtils.YEAR_SPAN)){
+				sDate = dateUtils.getLastDayOfLastYear(date);
+			}		
+		}
+		res.setData(customerService.businessStatistic(sDate,eDate,depId,businessGlossoryId,pageNo,pageSize));
+		return res;
+	}
+	
+	/**
+	 * 
+	 * @param startDate 开始日期
+	 * @param endDate 结束日期
+	 * @param timeSpan 时间差
+	 * @param depId 部门编号
+	 * @param businessGlossoryId 业务编号
+	 * @param pageNo 页码
+	 * @param pageSiz 页数
+	 * @return
+	 * @throws ParseException
+	 */
+	@SuppressWarnings("static-access")
+	@RequestMapping(value = "/followStatistic",method = RequestMethod.GET)
+	public Result followStatistic(String startDate,String endDate,String timeSpan,String depId,String businessGlossoryId,Integer pageNo, Integer pageSize) throws ParseException{
+		Result res = new Result();
+		Date sDate = null;
+		Date eDate = null;
+		DateUtils dateUtils = new DateUtils();
+		DateFormat format = new SimpleDateFormat(AFTConstants.YYYYMMDD);
+		if(StringUtils.isNotBlank(startDate)) sDate = format.parse(startDate);
+		if(StringUtils.isNotBlank(endDate)) eDate = format.parse(endDate);
+		if(StringUtils.isBlank(startDate)&&StringUtils.isBlank(endDate)){
+			Date date = new Date();
+			if(timeSpan.equals(DateUtils.DAY_SPAN)){
+				sDate = dateUtils.getYesterday();
+			}else if(timeSpan.equals(DateUtils.WEEK_SPAN)){
+				sDate = dateUtils.getLastDayOfLastWeek(date);
+			}else if(timeSpan.equals(DateUtils.MONTH_SPAN)){
+				sDate = dateUtils.getLastDayOfLastMonth(date);
+			}else if(timeSpan.equals(DateUtils.QUARTER_SPAN)){
+				sDate = dateUtils.getLastDayOfLastQuarter(date);
+			}else if(timeSpan.equals(DateUtils.YEAR_SPAN)){
+				sDate = dateUtils.getLastDayOfLastYear(date);
+			}		
+		}
+		res.setData(customerService.followStatistic(sDate, eDate, businessGlossoryId, depId, pageNo, pageSize));
+		return res;
+	}
 }

+ 27 - 0
src/main/java/com/goafanti/customer/service/CustomerService.java

@@ -1,5 +1,6 @@
 package com.goafanti.customer.service;
 
+import java.util.Date;
 import java.util.List;
 import java.util.Set;
 
@@ -16,6 +17,7 @@ import com.goafanti.customer.bo.CustomerPersonalDetailBo;
 import com.goafanti.customer.bo.CustomerSimpleBo;
 import com.goafanti.customer.bo.FollowBusinessBo;
 import com.goafanti.customer.bo.FollowListBo;
+import com.goafanti.customer.bo.StatisticBo;
 
 public interface CustomerService {
 	/**
@@ -224,4 +226,29 @@ public interface CustomerService {
 	 * @return
 	 */
 	int updateByOperatorType(String uid,String operatorType);
+	
+	/**
+	 * 客户统计
+	 * @param sDate
+	 * @param eDate
+	 * @param depId
+	 * @return
+	 */
+	Pagination<StatisticBo> customerStatistics(Date sDate, Date eDate, String depId,Integer pageNo, Integer pageSize);
+	
+	/**
+	 * 业务进度统计
+	 * @param sDate
+	 * @param eDate
+	 * @return
+	 */
+	Pagination<StatisticBo> businessStatistic(Date sDate, Date eDate, String businessGlossoryId, String depId, Integer pageNo, Integer pageSize);
+	
+	/**
+	 * 拜访统计
+	 * @param sDate
+	 * @param eDate
+	 * @return
+	 */
+	Pagination<StatisticBo> followStatistic(Date sDate, Date eDate,String businessGlossoryId, String depId, Integer pageNo, Integer pageSize);
 }

+ 93 - 39
src/main/java/com/goafanti/customer/service/impl/CustomerServiceImpl.java

@@ -29,6 +29,11 @@ import com.goafanti.common.dao.UserFollowBusinessMapper;
 import com.goafanti.common.dao.UserFollowMapper;
 import com.goafanti.common.dao.UserIdentityMapper;
 import com.goafanti.common.dao.UserMapper;
+import com.goafanti.common.enums.DeleteStatus;
+import com.goafanti.common.enums.IdentityProcess;
+import com.goafanti.common.enums.MemberStatus;
+import com.goafanti.common.enums.UserLevel;
+import com.goafanti.common.enums.UserType;
 import com.goafanti.common.error.BusinessException;
 import com.goafanti.common.model.OrganizationContactBook;
 import com.goafanti.common.model.OrganizationIdentity;
@@ -51,6 +56,7 @@ import com.goafanti.customer.bo.CustomerPersonalDetailBo;
 import com.goafanti.customer.bo.CustomerSimpleBo;
 import com.goafanti.customer.bo.FollowBusinessBo;
 import com.goafanti.customer.bo.FollowListBo;
+import com.goafanti.customer.bo.StatisticBo;
 import com.goafanti.customer.service.CustomerService;
 
 @Service
@@ -77,7 +83,7 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 	public Pagination<CustomerListOut> listPrivatePersonalCustomer(CustomerListIn cli, Integer pageNo,Integer pageSize) {
 		cli.setType(AFTConstants.USER_TYPE_PERSONAL);
 		cli.setAid(TokenManager.getAdminId());
-		cli.setShareType(String.valueOf(AFTConstants.SHARE_TYPE_PRIVATE));
+		cli.setShareType(String.valueOf(AFTConstants.USER_SHARE_PRIVATE));
 		Map<String,Object> params = disposeParams(cli);
 		@SuppressWarnings("unchecked")
 		Pagination<CustomerListOut> list = (Pagination<CustomerListOut>) findPage("selectPersonalCustomerList","selectPersonalCustomerCount",params,pageNo,pageSize);
@@ -88,7 +94,7 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 	public Pagination<CustomerListOut> listPublicPersonalCustomer(CustomerListIn cli, Integer pageNo,Integer pageSize) {
 		cli.setType(AFTConstants.USER_TYPE_PERSONAL);
 		cli.setAid(TokenManager.getAdminId());
-		cli.setShareType(String.valueOf(AFTConstants.SHARE_TYPE_PUBLIC));
+		cli.setShareType(String.valueOf(AFTConstants.USER_SHARE_PUBLIC));
 		Map<String,Object> params = disposeParams(cli);
 		@SuppressWarnings("unchecked")
 		Pagination<CustomerListOut> list = (Pagination<CustomerListOut>) findPage("selectPersonalCustomerList","selectPersonalCustomerCount",params,pageNo,pageSize);
@@ -108,7 +114,7 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 	public Pagination<CustomerListOut> listPrivateOrganizationCustomer(CustomerListIn cli, Integer pageNo,Integer pageSize) {
 		cli.setType(AFTConstants.USER_TYPE_ORGANIZATION);
 		cli.setAid(TokenManager.getAdminId());
-		cli.setShareType(String.valueOf(AFTConstants.SHARE_TYPE_PRIVATE));
+		cli.setShareType(String.valueOf(AFTConstants.USER_SHARE_PRIVATE));
 		Map<String,Object> params = disposeParams(cli);
 		@SuppressWarnings("unchecked")
 		Pagination<CustomerListOut> list = (Pagination<CustomerListOut>) findPage("selectOrganizationCustomerList","selectOrganizationCustomerCount",params,pageNo,pageSize);
@@ -119,7 +125,7 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 	public Pagination<CustomerListOut> listPublicOrganizationCustomer(CustomerListIn cli, Integer pageNo,Integer pageSize) {
 		cli.setType(AFTConstants.USER_TYPE_ORGANIZATION);
 		cli.setAid(TokenManager.getAdminId());
-		cli.setShareType(String.valueOf(AFTConstants.SHARE_TYPE_PUBLIC));
+		cli.setShareType(String.valueOf(AFTConstants.USER_SHARE_PUBLIC));
 		Map<String,Object> params = disposeParams(cli);
 		@SuppressWarnings("unchecked")
 		Pagination<CustomerListOut> list = (Pagination<CustomerListOut>) findPage("selectOrganizationCustomerList","selectOrganizationCustomerCount",params,pageNo,pageSize);
@@ -186,23 +192,23 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 		String identifyId = UUID.randomUUID().toString();
 		user.setId(uid);
 		user.setIdentifyName(name);
-		user.setSource(1);
+		user.setSource(AFTConstants.USER_SOURCE_CREATE);
 		user.setNickname(name);
-		user.setStatus(0);
-		user.setShareType(0);
+		user.setStatus(AFTConstants.USER_STATUS_NORMAL);
+		user.setShareType(AFTConstants.NO);
 		user.setAid(TokenManager.getAdminId());
 		user.setType(type);
-		user.setCurrentMemberStatus(0);
-		user.setLvl(1);
+		user.setCurrentMemberStatus(MemberStatus.NORMAL.getCode());
+		user.setLvl(UserLevel.CERTIFIED.getCode());
 		user.setSocietyTag(societyTag);
 		user.setCreateTime(now);
 		user.setUpdateTime(now);
 		user.setMobile(contactMobile);
 		user.setPassword(AFTConstants.INITIALPASSWORD);
-		user.setIsMember(0);
-		user.setBusinessAudit(0);
+		user.setIsMember(AFTConstants.YES);
+		user.setBusinessAudit(AFTConstants.NO);
 		passwordUtil.encryptPassword(user);
-		if(type == 0){
+		if(type == UserType.PERSONAL.getCode()){
 			if(userMapper.checkUser("", "", contactMobile, type).size()>0) throw new BusinessException(new Error(ErrorConstants.CUSTOMER_ALREADY_EXIST, name,""));
 			UserIdentity ui = new UserIdentity();
 			ui.setId(identifyId);
@@ -210,12 +216,12 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 			ui.setContacts(contacts);
 			ui.setContactMobile(contactMobile);
 			ui.setUsername(name);
-			ui.setExpert(0);
-			ui.setCelebrity(0);
-			ui.setInternational(0);
-			ui.setAuditStatus(5);//认证个人
+			ui.setExpert(AFTConstants.NO);
+			ui.setCelebrity(AFTConstants.NO);
+			ui.setInternational(AFTConstants.NO);
+			ui.setAuditStatus(IdentityProcess.SUCCESS.getCode());//认证个人
 			userIdentityMapper.insert(ui);
-		}else if(type == 1){
+		}else if(type == UserType.ORGANIZATION.getCode()){
 			if(userMapper.judgeCustomerByName(name)>0) throw new BusinessException(new Error(ErrorConstants.CUSTOMER_ALREADY_EXIST, name,""));
 			// 创建企业认证信息
 			OrganizationIdentity oi = new OrganizationIdentity();
@@ -224,10 +230,10 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 			oi.setUid(uid);
 			oi.setContacts(contacts);
 			oi.setContactMobile(contactMobile);
-			oi.setHighTechZone(0);
-			oi.setInternational(0);
-			oi.setListed(0);
-			oi.setAuditStatus(5); //实名企业
+			oi.setHighTechZone(AFTConstants.NO);
+			oi.setInternational(AFTConstants.NO);
+			oi.setListed(AFTConstants.NO);
+			oi.setAuditStatus(IdentityProcess.SUCCESS.getCode()); //实名企业
 			organizationIdentityMapper.insert(oi);
 		}
 		userMapper.insert(user);	
@@ -265,6 +271,7 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 			user.setCompanyLogoUrl(bo.getCompanyLogoUrl());
 			user.setIntroduction(bo.getIntroduction());
 			user.setUpdateTime(new Date());
+			user.setBusinessAudit(bo.getBusinessAudit());
 		} catch (IllegalAccessException |InvocationTargetException e) {
 			e.printStackTrace();
 		} 
@@ -284,6 +291,7 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 			user.setHeadPortraitUrl(bo.getHeadPortraitUrl());
 			user.setIntroduction(bo.getIntroduction());
 			user.setUpdateTime(new Date());
+			user.setBusinessAudit(bo.getBusinessAudit());
 		} catch (InvocationTargetException | IllegalAccessException e) {
 			e.printStackTrace();
 		}
@@ -329,7 +337,7 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 		userFollow.setId(followId);
 		userFollow.setAid(TokenManager.getAdminId());
 		userFollow.setContactType(Integer.parseInt(fbb.getContactType()));
-		userFollow.setEffective(0);
+		userFollow.setEffective(DeleteStatus.UNDELETE.getCode());
 		try {
 			userFollow.setCreateTime(format.parse(fbb.getFollowTime()));
 		} catch (ParseException e) {
@@ -509,7 +517,7 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 	public int deleteFollow(String followId) {
 		UserFollow uf = new UserFollow();
 		uf.setId(followId);
-		uf.setEffective(1);
+		uf.setEffective(DeleteStatus.DELETED.getCode());
 		return userFollowMapper.updateByPrimaryKeySelective(uf);
 	}
 
@@ -588,20 +596,20 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 		User user = new User();
 		user.setId(uid);
 		user.setIdentifyName(bo.getIdentifyName());
-		user.setSource(1);
+		user.setSource(AFTConstants.USER_SOURCE_CREATE);
 		user.setNickname(bo.getIdentifyName());
-		user.setStatus(0);
-		user.setShareType(0);
+		user.setStatus(AFTConstants.USER_STATUS_CANCEL);
+		user.setShareType(AFTConstants.USER_SHARE_PRIVATE);
 		user.setAid(TokenManager.getAdminId());
 		user.setType(Integer.parseInt(bo.getCustomerType()));
-		user.setCurrentMemberStatus(0);
-		user.setLvl(1);
+		user.setCurrentMemberStatus(MemberStatus.NORMAL.getCode());
+		user.setLvl(UserLevel.CERTIFIED.getCode());
 		user.setCreateTime(now);
 		user.setUpdateTime(now);
 		user.setMobile(bo.getMobile());
 		user.setPassword(AFTConstants.INITIALPASSWORD);
-		user.setIsMember(0);
-		user.setBusinessAudit(0);
+		user.setIsMember(AFTConstants.NO);
+		user.setBusinessAudit(AFTConstants.NO);
 		passwordUtil.encryptPassword(user);
 		userMapper.insert(user);	
 	}
@@ -616,10 +624,10 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 			ui.setContacts(bo.getContacts());
 			ui.setContactMobile(bo.getMobile());
 			ui.setUsername(bo.getIdentifyName());
-			ui.setExpert(0);
-			ui.setCelebrity(0);
-			ui.setInternational(0);
-			ui.setAuditStatus(0);
+			ui.setExpert(AFTConstants.NO);
+			ui.setCelebrity(AFTConstants.NO);
+			ui.setInternational(AFTConstants.NO);
+			ui.setAuditStatus(5);
 			userIdentityMapper.insert(ui);
 		}else if(type.equals(AFTConstants.USER_TYPE_ORGANIZATION)){
 			// 创建企业认证信息
@@ -629,9 +637,9 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 			oi.setUid(uid);
 			oi.setContacts(bo.getContacts());
 			oi.setContactMobile(bo.getMobile());
-			oi.setHighTechZone(0);
-			oi.setInternational(0);
-			oi.setListed(0);
+			oi.setHighTechZone(AFTConstants.NO);
+			oi.setInternational(AFTConstants.NO);
+			oi.setListed(AFTConstants.NO);
 			oi.setAuditStatus(5); //实名企业
 			organizationIdentityMapper.insert(oi);
 		}
@@ -667,13 +675,59 @@ public class CustomerServiceImpl  extends BaseMybatisDao<UserMapper> implements
 		User user = new User();
 		user.setId(uid);
 		if(operatorType.equals(AFTConstants.USER_TRANSFER_TO_PUBLIC)){
-			user.setShareType(AFTConstants.SHARE_TYPE_PUBLIC);
+			user.setShareType(AFTConstants.USER_SHARE_PUBLIC);
 		}else if(operatorType.equals(AFTConstants.USER_RECEIVE)){
 			user.setAid(TokenManager.getAdminId());
-			user.setShareType(AFTConstants.SHARE_TYPE_PRIVATE);
+			user.setShareType(AFTConstants.USER_SHARE_PRIVATE);
 		}else if(operatorType.equals(AFTConstants.USER_DELETE)){
 			user.setStatus(AFTConstants.USER_STATUS_CANCEL);
 		}
 		return userMapper.updateByPrimaryKeySelective(user);
 	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public Pagination<StatisticBo> customerStatistics(Date sDate, Date eDate, String depId ,Integer pageNo, Integer pageSize) {
+		Map<String,Object> params = new HashMap<String,Object>();
+		if(null != sDate) params.put("sDate", sDate);
+		if(null != eDate) params.put("eDate", eDate);
+		if(StringUtils.isNotBlank(depId)) params.put("departmentId", depId);
+		Pagination<StatisticBo> page = (Pagination<StatisticBo>)findPage("customerStatisticsList", "customerStatisticsCount", params, pageNo, pageSize);
+		return page;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public Pagination<StatisticBo> businessStatistic(Date sDate, Date eDate, String businessGlossoryId, String depId ,Integer pageNo, Integer pageSize) {
+		Map<String,Object> params = new HashMap<String,Object>();
+		if(null != sDate) params.put("sDate", sDate);
+		if(null != eDate) params.put("eDate", eDate);
+		if(StringUtils.isNotBlank(depId)) params.put("departmentId", depId);
+		if(StringUtils.isNoneBlank(businessGlossoryId)) params.put("businessGlossoryId", businessGlossoryId);
+		Pagination<StatisticBo> page = (Pagination<StatisticBo>)findPage("businessStatisticList", "businessStatisticCount", params, pageNo, pageSize);
+		return page;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public Pagination<StatisticBo> followStatistic(Date sDate, Date eDate, String businessGlossoryId, String depId ,Integer pageNo, Integer pageSize) {
+		Map<String,Object> params = new HashMap<String,Object>();
+		if(null != sDate) params.put("sDate", sDate);
+		if(null != eDate) params.put("eDate", eDate);
+		if(StringUtils.isNotBlank(depId)) params.put("departmentId", depId);
+		if(StringUtils.isNoneBlank(businessGlossoryId)) params.put("businessGlossoryId", businessGlossoryId);
+		Pagination<StatisticBo> page = (Pagination<StatisticBo>)findPage("followStatisticList", "followStatisticCount", params, pageNo, pageSize);
+		List<StatisticBo> list = (List<StatisticBo>)page.getList();
+		StatisticBo statisticBo = null;
+		for(StatisticBo bo:list){
+			statisticBo = userMapper.selectFollowAndCustomerCount(bo.getAid());
+				bo.setCustomerNo(statisticBo.getCustomerNo());
+				bo.setFollowNo(statisticBo.getFollowNo());
+		
+		}
+		page.setList(list);
+		return page;
+	}
+
+	
 }

+ 1 - 1
src/main/java/com/goafanti/memberGrade/controller/MemberGradeFrontController.java

@@ -112,7 +112,7 @@ public class MemberGradeFrontController extends BaseApiController {
 		Assert.isTrue(u != null && u.getLvl() > UserLevel.CERTIFIED.getCode(), "必须是登录实名用户");
 		Assert.hasText(uid, "找不到专家");
 		JSONObject business = memberGradeService.selectMemberBusiness(u.getLvl());
-		Assert.isTrue(AFTConstants.YES.equals(business.get(BusinessType.CHA_KAN_LIAN_XI.getKey())), "该会员不能查看专家联系方式");
+		Assert.isTrue(String.valueOf(AFTConstants.YES).equals(business.get(BusinessType.CHA_KAN_LIAN_XI.getKey())), "该会员不能查看专家联系方式");
 		UserIdentity ui = userIdentityService.selectUserIdentityByUserId(uid);
 		if (ui != null && StringUtils.isNotBlank(ui.getContactMobile())) {
 			return res().data(ui.getContactMobile());

+ 6 - 6
src/main/java/com/goafanti/user/controller/UserApiController.java

@@ -682,7 +682,7 @@ public class UserApiController extends BaseApiController {
 			}
 			if (MAX_WRONG_COUNT.equals(u.getWrongCount())) {
 				u.setAuditStatus(IdentityAuditStatus.NOTPASSED.getCode());// 4
-				u.setProcess(IdentityProcess.RESULTS.getCode());// 5
+				u.setProcess(IdentityProcess.SUCCESS.getCode());// 5
 				userIdentityService.updateByPrimaryKeySelective(u);
 				res.getError().add(buildError(ErrorConstants.OVER_MAX_WRONG_COUNT));// 输入错误金额次数过多
 				return res;
@@ -693,7 +693,7 @@ public class UserApiController extends BaseApiController {
 
 				if (0 == t) {
 					u.setAuditStatus(IdentityAuditStatus.NOTPASSED.getCode());// 4
-					u.setProcess(IdentityProcess.RESULTS.getCode());// 5
+					u.setProcess(IdentityProcess.SUCCESS.getCode());// 5
 					res.getError().add(buildError(ErrorConstants.OVER_MAX_WRONG_COUNT));// 输入错误金额次数过多
 				} else {
 					res.getError().add(buildError(ErrorConstants.WRONG_MONEY, "", t));
@@ -702,7 +702,7 @@ public class UserApiController extends BaseApiController {
 				return res;
 			}
 			userIdentity.setAuditStatus(IdentityAuditStatus.PASSED.getCode());
-			userIdentity.setProcess(IdentityProcess.RESULTS.getCode());
+			userIdentity.setProcess(IdentityProcess.SUCCESS.getCode());
 		}
 		return dealUserProcess(res, userIdentity, TokenManager.getUserId());
 	}
@@ -760,7 +760,7 @@ public class UserApiController extends BaseApiController {
 			}
 			if (MAX_WRONG_COUNT.equals(o.getWrongCount())) {
 				o.setAuditStatus(IdentityAuditStatus.NOTPASSED.getCode());// 4
-				o.setProcess(IdentityProcess.RESULTS.getCode());// 5
+				o.setProcess(IdentityProcess.SUCCESS.getCode());// 5
 				organizationIdentityService.updateByPrimaryKeySelective(o);
 				res.getError().add(buildError(ErrorConstants.OVER_MAX_WRONG_COUNT));// 输入错误金额次数过多
 				return res;
@@ -770,7 +770,7 @@ public class UserApiController extends BaseApiController {
 				o.setWrongCount(o.getWrongCount() + 1);
 				if (0 == t) {
 					o.setAuditStatus(IdentityAuditStatus.NOTPASSED.getCode());// 4
-					o.setProcess(IdentityProcess.RESULTS.getCode());// 5
+					o.setProcess(IdentityProcess.SUCCESS.getCode());// 5
 					res.getError().add(buildError(ErrorConstants.OVER_MAX_WRONG_COUNT));// 输入错误金额次数过多
 				} else {
 					res.getError().add(buildError(ErrorConstants.WRONG_MONEY, "", t));
@@ -779,7 +779,7 @@ public class UserApiController extends BaseApiController {
 				return res;
 			}
 			orgIdentity.setAuditStatus(IdentityAuditStatus.PASSED.getCode());
-			orgIdentity.setProcess(IdentityProcess.RESULTS.getCode());
+			orgIdentity.setProcess(IdentityProcess.SUCCESS.getCode());
 		}
 		return dealOrgProcess(res, orgIdentity, TokenManager.getUserId());
 	}

+ 0 - 2
src/main/java/com/goafanti/user/service/impl/UserIdentityServiceImpl.java

@@ -13,7 +13,6 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CacheEvict;
-import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
 import com.goafanti.common.bo.Result;
@@ -34,7 +33,6 @@ import com.goafanti.common.utils.LoggerUtils;
 import com.goafanti.core.mybatis.BaseMybatisDao;
 import com.goafanti.core.mybatis.page.Pagination;
 import com.goafanti.core.shiro.token.TokenManager;
-import com.goafanti.portal.bo.InternationalListBo;
 import com.goafanti.portal.bo.UserSubscriberListBo;
 import com.goafanti.user.bo.AuditorUserIdentityDetailBo;
 import com.goafanti.user.bo.UserIdentityBo;

+ 520 - 0
src/main/resources/spring-context-4.0.xsd

@@ -0,0 +1,520 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsd:schema xmlns="http://www.springframework.org/schema/context"
+		xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+		xmlns:beans="http://www.springframework.org/schema/beans"
+		xmlns:tool="http://www.springframework.org/schema/tool"
+		targetNamespace="http://www.springframework.org/schema/context"
+		elementFormDefault="qualified"
+		attributeFormDefault="unqualified">
+
+	<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"/>
+	<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-4.0.xsd"/>
+
+	<xsd:annotation>
+		<xsd:documentation><![CDATA[
+	Defines the configuration elements for the Spring Framework's application
+	context support. Effects the activation of various configuration styles
+	for the containing Spring ApplicationContext.
+		]]></xsd:documentation>
+	</xsd:annotation>
+
+	<xsd:complexType name="propertyPlaceholder">
+		<xsd:attribute name="location" type="xsd:string">
+			<xsd:annotation>
+				<xsd:documentation><![CDATA[
+	The location of the properties file to resolve placeholders against, as a Spring
+	resource location: a URL, a "classpath:" pseudo URL, or a relative file path.
+	Multiple locations may be specified, separated by commas. If neither location nor
+	properties-ref is specified, placeholders will be resolved against system properties.
+				]]></xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+		<xsd:attribute name="properties-ref" type="xsd:string">
+			<xsd:annotation>
+				<xsd:documentation source="java:java.util.Properties"><![CDATA[
+	The bean name of a Properties object that will be used for property substitution.
+	If neither location nor properties-ref is specified, placeholders will be resolved
+	against system properties.
+				]]></xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+		<xsd:attribute name="file-encoding" type="xsd:string">
+			<xsd:annotation>
+				<xsd:documentation><![CDATA[
+	Specifies the encoding to use for parsing properties files. Default is none,
+	using the java.util.Properties default encoding. Only applies to classic
+	properties files, not to XML files.
+				]]></xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+		<xsd:attribute name="order" type="xsd:token">
+			<xsd:annotation>
+				<xsd:documentation><![CDATA[
+	Specifies the order for this placeholder configurer. If more than one is present
+	in a context, the order can be important since the first one to be match a
+	placeholder will win.
+				]]></xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+		<xsd:attribute name="ignore-resource-not-found" type="xsd:boolean" default="false">
+			<xsd:annotation>
+				<xsd:documentation><![CDATA[
+	Specifies if failure to find the property resource location should be ignored.
+	Default is "false", meaning that if there is no file in the location specified
+	an exception will be raised at runtime.
+				]]></xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+		<xsd:attribute name="ignore-unresolvable" type="xsd:boolean" default="false">
+			<xsd:annotation>
+				<xsd:documentation><![CDATA[
+	Specifies if failure to find the property value to replace a key should be ignored.
+	Default is "false", meaning that this placeholder configurer will raise an exception
+	if it cannot resolve a key. Set to "true" to allow the configurer to pass on the key
+	to any others in the context that have not yet visited the key in question.
+				]]></xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+		<xsd:attribute name="local-override" type="xsd:boolean" default="false">
+			<xsd:annotation>
+				<xsd:documentation><![CDATA[
+	Specifies whether local properties override properties from files.
+	Default is "false": Properties from files override local defaults.
+				]]></xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+	</xsd:complexType>
+
+	<xsd:element name="property-placeholder">
+		<xsd:annotation>
+			<xsd:documentation><![CDATA[
+	Activates replacement of ${...} placeholders by registering a
+	PropertySourcesPlaceholderConfigurer within the application context. Properties will
+	be resolved against the specified properties file or Properties object -- so called
+	"local properties", if any, and against the Spring Environment's current set of
+	PropertySources.
+
+	Note that as of Spring 3.1 the system-properties-mode attribute has been removed in
+	favor of the more flexible PropertySources mechanism. However, Spring 3.1-based
+	applications may continue to use the 3.0 (and older) versions of the spring-context
+	schema in order to preserve system-properties-mode behavior. In this case, the
+	traditional PropertyPlaceholderConfigurer component will be registered instead of the
+	new PropertySourcesPlaceholderConfigurer.
+
+	See ConfigurableEnvironment javadoc for more information on using.
+			]]></xsd:documentation>
+			<xsd:appinfo>
+				<tool:annotation>
+					<tool:exports type="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
+				</tool:annotation>
+			</xsd:appinfo>
+		</xsd:annotation>
+		<xsd:complexType>
+			<xsd:complexContent>
+				<xsd:extension base="propertyPlaceholder">
+					<xsd:attribute name="system-properties-mode" default="ENVIRONMENT">
+						<xsd:annotation>
+							<xsd:documentation><![CDATA[
+	Controls how to resolve placeholders against system properties. As of Spring 3.1, this
+	attribute value defaults to "ENVIRONMENT", indicating that resolution of placeholders
+	against system properties is handled via PropertySourcesPlaceholderConfigurer and its
+	delegation to the current Spring Environment object.
+
+	For maximum backward compatibility, this attribute is preserved going forward with the
+	3.1 version of the context schema, and any values other than the default "ENVIRONMENT"
+	will cause a traditional PropertyPlaceholderConfigurer to be registered instead of the
+	newer PropertySourcesPlaceholderConfigurer variant. In this case, the Spring Environment
+	and its property sources are not interrogated when resolving placeholders. Users are
+	encouraged to consider this attribute deprecated, and to take advantage of
+	Environment/PropertySource mechanisms. See ConfigurableEnvironment javadoc for examples.
+
+	"ENVIRONMENT" indicates placeholders should be resolved against the current Environment and against any local properties;
+	"NEVER" indicates placeholders should be resolved only against local properties and never against system properties;
+	"FALLBACK" indicates placeholders should be resolved against any local properties and then against system properties;
+	"OVERRIDE" indicates placeholders should be resolved first against system properties and then against any local properties;
+							]]></xsd:documentation>
+						</xsd:annotation>
+						<xsd:simpleType>
+							<xsd:restriction base="xsd:string">
+								<xsd:enumeration value="ENVIRONMENT"/>
+								<xsd:enumeration value="NEVER"/>
+								<xsd:enumeration value="FALLBACK"/>
+								<xsd:enumeration value="OVERRIDE"/>
+							</xsd:restriction>
+						</xsd:simpleType>
+					</xsd:attribute>
+				</xsd:extension>
+			</xsd:complexContent>
+		</xsd:complexType>
+	</xsd:element>
+
+	<xsd:element name="property-override">
+		<xsd:annotation>
+			<xsd:documentation><![CDATA[
+	Activates pushing of override values into bean properties, based on configuration
+	lines of the following format: beanName.property=value
+			]]></xsd:documentation>
+			<xsd:appinfo>
+				<tool:annotation>
+					<tool:exports type="org.springframework.beans.factory.config.PropertyOverrideConfigurer"/>
+				</tool:annotation>
+			</xsd:appinfo>
+		</xsd:annotation>
+		<xsd:complexType>
+			<xsd:complexContent>
+				<xsd:extension base="propertyPlaceholder"/>
+			</xsd:complexContent>
+		</xsd:complexType>
+	</xsd:element>
+
+	<xsd:element name="annotation-config">
+		<xsd:annotation>
+			<xsd:documentation><![CDATA[
+	Activates various annotations to be detected in bean classes: Spring's @Required and
+	@Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
+	JAX-WS's @WebServiceRef (if available), EJB3's @EJB (if available), and JPA's
+	@PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
+	choose to activate the individual BeanPostProcessors for those annotations.
+
+	Note: This tag does not activate processing of Spring's @Transactional or EJB3's
+	@TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
+	tag for that purpose.
+
+	See javadoc for org.springframework.context.annotation.AnnotationConfigApplicationContext
+	for information on code-based alternatives to bootstrapping annotation-driven support.
+	from XML.
+			]]></xsd:documentation>
+		</xsd:annotation>
+	</xsd:element>
+
+	<xsd:element name="component-scan">
+		<xsd:annotation>
+			<xsd:documentation><![CDATA[
+	Scans the classpath for annotated components that will be auto-registered as
+	Spring beans. By default, the Spring-provided @Component, @Repository,
+	@Service, and @Controller stereotypes will be detected.
+
+	Note: This tag implies the effects of the 'annotation-config' tag, activating @Required,
+	@Autowired, @PostConstruct, @PreDestroy, @Resource, @PersistenceContext and @PersistenceUnit
+	annotations in the component classes, which is usually desired for autodetected components
+	(without external configuration). Turn off the 'annotation-config' attribute to deactivate
+	this default behavior, for example in order to use custom BeanPostProcessor definitions
+	for handling those annotations.
+
+	Note: You may use placeholders in package paths, but only resolved against system
+	properties (analogous to resource paths). A component scan results in new bean definition
+	being registered; Spring's PropertyPlaceholderConfigurer will apply to those bean
+	definitions just like to regular bean definitions, but it won't apply to the component
+	scan settings themselves.
+
+	See javadoc for org.springframework.context.annotation.ComponentScan for information
+	on code-based alternatives to bootstrapping component-scanning.
+			]]></xsd:documentation>
+		</xsd:annotation>
+		<xsd:complexType>
+			<xsd:sequence>
+				<xsd:element name="include-filter" type="filterType"
+					minOccurs="0" maxOccurs="unbounded">
+					<xsd:annotation>
+						<xsd:documentation><![CDATA[
+	Controls which eligible types to include for component scanning.
+							]]></xsd:documentation>
+					</xsd:annotation>
+				</xsd:element>
+				<xsd:element name="exclude-filter" type="filterType"
+					minOccurs="0" maxOccurs="unbounded">
+					<xsd:annotation>
+						<xsd:documentation><![CDATA[
+	Controls which eligible types to exclude for component scanning.
+						]]></xsd:documentation>
+					</xsd:annotation>
+				</xsd:element>
+			</xsd:sequence>
+			<xsd:attribute name="base-package" type="xsd:string"
+				use="required">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	The comma/semicolon/space/tab/linefeed-separated list of packages to scan for annotated components.
+					]]></xsd:documentation>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="resource-pattern" type="xsd:string">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	Controls the class files eligible for component detection. Defaults to "**/*.class", the recommended value.
+	Consider use of the include-filter and exclude-filter elements for a more fine-grained approach.
+					]]></xsd:documentation>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="use-default-filters" type="xsd:boolean"
+				default="true">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	Indicates whether automatic detection of classes annotated with @Component, @Repository, @Service,
+	or @Controller should be enabled. Default is "true".
+					]]></xsd:documentation>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="annotation-config" type="xsd:boolean"
+				default="true">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	Indicates whether the implicit annotation post-processors should be enabled. Default is "true".
+					]]></xsd:documentation>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="name-generator" type="xsd:string">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	The fully-qualified class name of the BeanNameGenerator to be used for naming detected components.
+					]]></xsd:documentation>
+					<xsd:appinfo>
+						<tool:annotation>
+							<tool:expected-type type="java.lang.Class"/>
+							<tool:assignable-to type="org.springframework.beans.factory.support.BeanNameGenerator"/>
+						</tool:annotation>
+					</xsd:appinfo>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="scope-resolver" type="xsd:string">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	The fully-qualified class name of the ScopeMetadataResolver to be used for resolving the scope of
+	detected components.
+					]]></xsd:documentation>
+					<xsd:appinfo>
+						<tool:annotation>
+							<tool:expected-type type="java.lang.Class"/>
+							<tool:assignable-to type="org.springframework.context.annotation.ScopeMetadataResolver"/>
+						</tool:annotation>
+					</xsd:appinfo>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="scoped-proxy">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	Indicates whether proxies should be generated for detected components, which may be necessary
+	when using scopes in a proxy-style fashion. Default is to generate no such proxies.
+					]]></xsd:documentation>
+				</xsd:annotation>
+				<xsd:simpleType>
+					<xsd:restriction base="xsd:string">
+						<xsd:enumeration value="no"/>
+						<xsd:enumeration value="interfaces"/>
+						<xsd:enumeration value="targetClass"/>
+					</xsd:restriction>
+				</xsd:simpleType>
+			</xsd:attribute>
+		</xsd:complexType>
+	</xsd:element>
+
+	<xsd:element name="load-time-weaver">
+		<xsd:annotation>
+			<xsd:documentation><![CDATA[
+	Activates a Spring LoadTimeWeaver for this application context, available as
+	a bean with the name "loadTimeWeaver". Any bean that implements the
+	LoadTimeWeaverAware interface will then receive the LoadTimeWeaver reference
+	automatically; for example, Spring's JPA bootstrap support.
+
+	The default weaver is determined automatically: see DefaultContextLoadTimeWeaver's
+	javadoc for details.
+
+	The activation of AspectJ load-time weaving is specified via a simple flag
+	(the 'aspectj-weaving' attribute), with the AspectJ class transformer
+	registered through Spring's LoadTimeWeaver. AspectJ weaving will be activated
+	by default if a "META-INF/aop.xml" resource is present in the classpath.
+
+	This also activates the current application context for applying dependency
+	injection to non-managed classes that are instantiated outside of the Spring
+	bean factory (typically classes annotated with the @Configurable annotation).
+	This will only happen if the AnnotationBeanConfigurerAspect is on the classpath
+	(i.e. spring-aspects.jar), effectively activating "spring-configured" by default.
+
+	See javadoc for org.springframework.context.annotation.EnableLoadTimeWeaving
+	for information on code-based alternatives to bootstrapping load-time weaving support.
+			]]></xsd:documentation>
+			<xsd:appinfo>
+				<tool:annotation>
+					<tool:exports type="org.springframework.instrument.classloading.LoadTimeWeaver"/>
+				</tool:annotation>
+			</xsd:appinfo>
+		</xsd:annotation>
+		<xsd:complexType>
+			<xsd:attribute name="weaver-class" type="xsd:string">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	The fully-qualified classname of the LoadTimeWeaver that is to be activated.
+					]]></xsd:documentation>
+					<xsd:appinfo>
+						<tool:annotation>
+							<tool:expected-type type="java.lang.Class"/>
+							<tool:assignable-to type="org.springframework.instrument.classloading.LoadTimeWeaver"/>
+						</tool:annotation>
+					</xsd:appinfo>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="aspectj-weaving" default="autodetect">
+				<xsd:simpleType>
+					<xsd:restriction base="xsd:string">
+						<xsd:enumeration value="on">
+							<xsd:annotation>
+								<xsd:documentation><![CDATA[
+	Switches Spring-based AspectJ load-time weaving on.
+								]]></xsd:documentation>
+							</xsd:annotation>
+						</xsd:enumeration>
+						<xsd:enumeration value="off">
+							<xsd:annotation>
+								<xsd:documentation><![CDATA[
+	Switches Spring-based AspectJ load-time weaving off.
+								]]></xsd:documentation>
+							</xsd:annotation>
+						</xsd:enumeration>
+						<xsd:enumeration value="autodetect">
+							<xsd:annotation>
+								<xsd:documentation><![CDATA[
+	Switches AspectJ load-time weaving on if a "META-INF/aop.xml" resource
+	is present in the classpath. If there is no such resource, then AspectJ
+	load-time weaving will be switched off.
+								]]></xsd:documentation>
+							</xsd:annotation>
+						</xsd:enumeration>
+					</xsd:restriction>
+				</xsd:simpleType>
+			</xsd:attribute>
+		</xsd:complexType>
+	</xsd:element>
+
+	<xsd:element name="spring-configured">
+		<xsd:annotation>
+			<xsd:documentation source="java:org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"><![CDATA[
+	Signals the current application context to apply dependency injection
+	to non-managed classes that are instantiated outside of the Spring bean
+	factory (typically classes annotated with the @Configurable annotation).
+			]]></xsd:documentation>
+		</xsd:annotation>
+		<xsd:simpleType>
+			<xsd:restriction base="xsd:string"/>
+		</xsd:simpleType>
+	</xsd:element>
+
+	<xsd:element name="mbean-export">
+		<xsd:annotation>
+			<xsd:documentation source="java:org.springframework.jmx.export.annotation.AnnotationMBeanExporter"><![CDATA[
+	Activates default exporting of MBeans by detecting standard MBeans in the Spring
+	context as well as @ManagedResource annotations on Spring-defined beans.
+
+	The resulting MBeanExporter bean is defined under the name "mbeanExporter".
+	Alternatively, consider defining a custom AnnotationMBeanExporter bean explicitly.
+			]]></xsd:documentation>
+			<xsd:appinfo>
+				<tool:annotation>
+					<tool:exports type="org.springframework.jmx.export.annotation.AnnotationMBeanExporter"/>
+				</tool:annotation>
+			</xsd:appinfo>
+		</xsd:annotation>
+		<xsd:complexType>
+			<xsd:attribute name="default-domain" type="xsd:string">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	The default domain to use when generating JMX ObjectNames.
+					]]></xsd:documentation>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="server" type="xsd:string">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	The bean name of the MBeanServer to which MBeans should be exported.
+	Default is to use the platform's default MBeanServer (autodetecting
+	WebLogic, WebSphere and the JVM's platform MBeanServer).
+					]]></xsd:documentation>
+				</xsd:annotation>
+			</xsd:attribute>
+			<xsd:attribute name="registration">
+				<xsd:annotation>
+					<xsd:documentation><![CDATA[
+	The registration behavior, indicating how to deal with existing MBeans
+	of the same name: fail with an exception, ignore and keep the existing
+	MBean, or replace the existing one with the new MBean.
+
+	Default is to fail with an exception.
+					]]></xsd:documentation>
+				</xsd:annotation>
+				<xsd:simpleType>
+					<xsd:restriction base="xsd:NMTOKEN">
+						<xsd:enumeration value="failOnExisting"/>
+						<xsd:enumeration value="ignoreExisting"/>
+						<xsd:enumeration value="replaceExisting"/>
+					</xsd:restriction>
+				</xsd:simpleType>
+			</xsd:attribute>
+		</xsd:complexType>
+	</xsd:element>
+
+	<xsd:element name="mbean-server">
+		<xsd:annotation>
+			<xsd:documentation source="java:org.springframework.jmx.support.MBeanServerFactoryBean"><![CDATA[
+	Exposes a default MBeanServer for the current platform.
+	Autodetects WebLogic, WebSphere and the JVM's platform MBeanServer.
+
+	The default bean name for the exposed MBeanServer is "mbeanServer".
+	This may be customized through specifying the "id" attribute.
+			]]></xsd:documentation>
+			<xsd:appinfo>
+				<tool:annotation>
+					<tool:exports type="javax.management.MBeanServer"/>
+				</tool:annotation>
+			</xsd:appinfo>
+		</xsd:annotation>
+		<xsd:complexType>
+			<xsd:complexContent>
+				<xsd:extension base="beans:identifiedType">
+					<xsd:attribute name="agent-id" type="xsd:string">
+						<xsd:annotation>
+							<xsd:documentation><![CDATA[
+	The agent id of the target MBeanServer, if any.
+							]]></xsd:documentation>
+						</xsd:annotation>
+					</xsd:attribute>
+				</xsd:extension>
+			</xsd:complexContent>
+		</xsd:complexType>
+	</xsd:element>
+
+	<xsd:complexType name="filterType">
+		<xsd:attribute name="type" use="required">
+			<xsd:annotation>
+				<xsd:documentation><![CDATA[
+    Controls the type of filtering to apply to the expression.
+
+    "annotation" indicates an annotation to be present at the type level in target components;
+    "assignable" indicates a class (or interface) that the target components are assignable to (extend/implement);
+    "aspectj" indicates an AspectJ type pattern expression to be matched by the target components;
+    "regex" indicates a regex pattern to be matched by the target components' class names;
+    "custom" indicates a custom implementation of the org.springframework.core.type.TypeFilter interface.
+
+    Note: This attribute will not be inherited by child bean definitions.
+    Hence, it needs to be specified per concrete bean definition.
+                ]]></xsd:documentation>
+			</xsd:annotation>
+			<xsd:simpleType>
+				<xsd:restriction base="xsd:string">
+					<xsd:enumeration value="annotation"/>
+					<xsd:enumeration value="assignable"/>
+					<xsd:enumeration value="aspectj"/>
+					<xsd:enumeration value="regex"/>
+					<xsd:enumeration value="custom"/>
+				</xsd:restriction>
+			</xsd:simpleType>
+		</xsd:attribute>
+		<xsd:attribute name="expression" type="xsd:string" use="required">
+			<xsd:annotation>
+				<xsd:documentation><![CDATA[
+    Indicates the filter expression, the type of which is indicated by "type".
+                ]]></xsd:documentation>
+			</xsd:annotation>
+		</xsd:attribute>
+	</xsd:complexType>
+
+</xsd:schema>