This commit is contained in:
磷叶 2025-03-10 15:30:57 +08:00
parent 0fd1bccca4
commit eefba25d17
27 changed files with 284 additions and 31 deletions

View File

@ -43,13 +43,11 @@ public class Customer extends BaseEntity
@Excel(name = "状态", readConverterExp = "1=潜在,2=意向,3=成交,4=失效") @Excel(name = "状态", readConverterExp = "1=潜在,2=意向,3=成交,4=失效")
@ApiModelProperty("状态") @ApiModelProperty("状态")
@NotBlank(message = "状态不能为空", groups = {ValidGroup.Create.class})
@DictValid(type = DictType.CUSTOMER_STATUS, message = "非法的状态值") @DictValid(type = DictType.CUSTOMER_STATUS, message = "非法的状态值")
private String status; private String status;
@Excel(name = "意向强度", readConverterExp = "1=高,2=中,3=低") @Excel(name = "意向强度", readConverterExp = "1=高,2=中,3=低")
@ApiModelProperty("意向强度") @ApiModelProperty("意向强度")
@NotBlank(message = "意向强度不能为空", groups = {ValidGroup.Create.class})
@DictValid(type = DictType.CUSTOMER_INTENT_LEVEL, message = "非法的意向强度值") @DictValid(type = DictType.CUSTOMER_INTENT_LEVEL, message = "非法的意向强度值")
private String intentLevel; private String intentLevel;

View File

@ -39,6 +39,14 @@ public class CustomerQuery extends CustomerVO{
@DateTimeFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate nextFollowDate; private LocalDate nextFollowDate;
@ApiModelProperty("下次跟进日期开始")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate nextFollowDateStart;
@ApiModelProperty("下次跟进日期结束")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate nextFollowDateEnd;
@ApiModelProperty("创建日期范围") @ApiModelProperty("创建日期范围")
@DateTimeFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd")
private List<LocalDate> createDateRange; private List<LocalDate> createDateRange;
@ -50,4 +58,7 @@ public class CustomerQuery extends CustomerVO{
@ApiModelProperty("下次跟进时间结束") @ApiModelProperty("下次跟进时间结束")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime nextFollowTimeEnd; private LocalDateTime nextFollowTimeEnd;
@ApiModelProperty("客户状态列表")
private List<String> statusList;
} }

View File

@ -1,5 +1,9 @@
package com.ruoyi.bst.customer.domain.enums; package com.ruoyi.bst.customer.domain.enums;
import java.util.List;
import com.ruoyi.common.utils.collection.CollectionUtils;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@ -15,4 +19,12 @@ public enum CustomerStatus {
private final String status; private final String status;
private final String name; private final String name;
/**
* 跟进中的客户状态
* @return
*/
public static List<String> following() {
return CollectionUtils.map(CustomerStatus::getStatus, POTENTIAL, INTENTION, TRANSACTION);
}
} }

View File

@ -32,6 +32,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bc.demand, bc.demand,
suf.nick_name as follow_name, suf.nick_name as follow_name,
su.nick_name as create_name su.nick_name as create_name
<include refid="searchTables"/>
</sql>
<sql id="searchTables">
from bst_customer bc from bst_customer bc
left join sys_user suf on suf.user_id = bc.follow_id left join sys_user suf on suf.user_id = bc.follow_id
left join sys_user su on su.user_id = bc.create_id left join sys_user su on su.user_id = bc.create_id
@ -65,6 +69,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.nextFollowDate != null "> and date(bc.next_follow_time) = #{query.nextFollowDate}</if> <if test="query.nextFollowDate != null "> and date(bc.next_follow_time) = #{query.nextFollowDate}</if>
<if test="query.nextFollowTimeStart != null "> and bc.next_follow_time &gt;= #{query.nextFollowTimeStart}</if> <if test="query.nextFollowTimeStart != null "> and bc.next_follow_time &gt;= #{query.nextFollowTimeStart}</if>
<if test="query.nextFollowTimeEnd != null "> and bc.next_follow_time &lt;= #{query.nextFollowTimeEnd}</if> <if test="query.nextFollowTimeEnd != null "> and bc.next_follow_time &lt;= #{query.nextFollowTimeEnd}</if>
<if test="query.nextFollowDateStart != null "> and date(bc.next_follow_time) &gt;= #{query.nextFollowDateStart}</if>
<if test="query.nextFollowDateEnd != null "> and date(bc.next_follow_time) &lt;= #{query.nextFollowDateEnd}</if>
<if test="query.statusList != null and query.statusList.size() > 0">
and bc.status in
<foreach collection="query.statusList" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="query.createDateRange != null and query.createDateRange.size() > 1"> <if test="query.createDateRange != null and query.createDateRange.size() > 1">
and date(bc.create_time) >= #{query.createDateRange[0]} and date(bc.create_time) >= #{query.createDateRange[0]}
and date(bc.create_time) &lt;= #{query.createDateRange[1]} and date(bc.create_time) &lt;= #{query.createDateRange[1]}
@ -186,7 +198,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<!-- selectCount --> <!-- selectCount -->
<select id="selectCount" parameterType="CustomerQuery" resultType="Integer"> <select id="selectCount" parameterType="CustomerQuery" resultType="Integer">
select count(bc.id) from bst_customer bc select count(bc.id)
<include refid="searchTables"/>
<where> <where>
<include refid="searchCondition"/> <include refid="searchCondition"/>
</where> </where>
@ -198,7 +211,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select select
bc.status as `key`, bc.status as `key`,
count(bc.id) as `value` count(bc.id) as `value`
from bst_customer bc <include refid="searchTables"/>
<where> <where>
<include refid="searchCondition"/> <include refid="searchCondition"/>
</where> </where>
@ -240,7 +253,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select select
date(bc.create_time) as `key`, date(bc.create_time) as `key`,
count(bc.id) as `value` count(bc.id) as `value`
from bst_customer bc <include refid="searchTables"/>
<where> <where>
<include refid="searchCondition"/> <include refid="searchCondition"/>
</where> </where>

View File

@ -17,19 +17,22 @@ public class CustomerConverterImpl implements CustomerConverter {
} }
CustomerAddDTO po = new CustomerAddDTO(); CustomerAddDTO po = new CustomerAddDTO();
po.setName(customer.getName()); po.setName(customer.getName());
po.setStatus(customer.getStatus());
po.setIntentLevel(customer.getIntentLevel());
po.setMobile(customer.getMobile()); po.setMobile(customer.getMobile());
po.setWechat(customer.getWechat()); po.setWechat(customer.getWechat());
po.setSource(customer.getSource()); po.setSource(customer.getSource());
po.setIntents(customer.getIntents()); po.setIntents(customer.getIntents());
po.setRemark(customer.getRemark()); po.setRemark(customer.getRemark());
po.setFollow(customer.getFollow());
po.setFollowId(customer.getFollowId()); po.setFollowId(customer.getFollowId());
po.setConcern(customer.getConcern()); po.setConcern(customer.getConcern());
po.setPain(customer.getPain()); po.setPain(customer.getPain());
po.setAttention(customer.getAttention()); po.setAttention(customer.getAttention());
po.setDemand(customer.getDemand()); po.setDemand(customer.getDemand());
if (customer.getFollow() != null) {
CustomerFollow follow = customer.getFollow();
po.setStatus(follow.getCustomerStatus());
po.setIntentLevel(follow.getCustomerIntentLevel());
po.setFollow(follow);
}
return po; return po;
} }

View File

@ -0,0 +1,8 @@
package com.ruoyi.bst.customer.utils;
public class CustomerQueryUtil {
}

View File

@ -65,4 +65,14 @@ public class CustomerFollow extends BaseEntity
@ApiModelProperty("跟进时间") @ApiModelProperty("跟进时间")
@Past(message = "跟进时间不能大于当前时间") @Past(message = "跟进时间不能大于当前时间")
private LocalDateTime followTime; private LocalDateTime followTime;
@ApiModelProperty("客户状态")
@NotBlank(message = "客户状态不能为空", groups = {ValidGroup.Create.class} )
@DictValid(type = DictType.CUSTOMER_STATUS, message = "非法的客户状态值")
private String customerStatus;
@ApiModelProperty("客户意向强度")
@NotBlank(message = "客户意向强度不能为空", groups = {ValidGroup.Create.class})
@DictValid(type = DictType.CUSTOMER_INTENT_LEVEL, message = "非法的意向强度值")
private String customerIntentLevel;
} }

View File

@ -17,6 +17,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bcf.next_follow_time, bcf.next_follow_time,
bcf.create_time, bcf.create_time,
bcf.follow_time, bcf.follow_time,
bcf.customer_status,
bcf.customer_intent_level,
bc.name as customer_name, bc.name as customer_name,
bc.code as customer_code, bc.code as customer_code,
su.nick_name as user_name su.nick_name as user_name
@ -34,6 +36,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.customerName != null and query.customerName != ''"> and bc.name like concat('%', #{query.customerName}, '%')</if> <if test="query.customerName != null and query.customerName != ''"> and bc.name like concat('%', #{query.customerName}, '%')</if>
<if test="query.customerCode != null and query.customerCode != ''"> and bc.code like concat('%', #{query.customerCode}, '%')</if> <if test="query.customerCode != null and query.customerCode != ''"> and bc.code like concat('%', #{query.customerCode}, '%')</if>
<if test="query.userName != null and query.userName != ''"> and su.nick_name like concat('%', #{query.userName}, '%')</if> <if test="query.userName != null and query.userName != ''"> and su.nick_name like concat('%', #{query.userName}, '%')</if>
<if test="query.customerStatus != null and query.customerStatus != ''"> and bcf.customer_status = #{query.customerStatus}</if>
<if test="query.customerIntentLevel != null and query.customerIntentLevel != ''"> and bcf.customer_intent_level = #{query.customerIntentLevel}</if>
${@com.ruoyi.framework.util.DataScopeUtil@dataScope( ${@com.ruoyi.framework.util.DataScopeUtil@dataScope(
null, null,
"bcf.user_id", "bcf.user_id",
@ -66,6 +70,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="userId != null">user_id,</if> <if test="userId != null">user_id,</if>
<if test="nextFollowTime != null">next_follow_time,</if> <if test="nextFollowTime != null">next_follow_time,</if>
<if test="followTime != null">follow_time,</if> <if test="followTime != null">follow_time,</if>
<if test="customerStatus != null and customerStatus != ''">customer_status,</if>
<if test="customerIntentLevel != null and customerIntentLevel != ''">customer_intent_level,</if>
<if test="createTime != null">create_time,</if> <if test="createTime != null">create_time,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
@ -76,6 +82,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="userId != null">#{userId},</if> <if test="userId != null">#{userId},</if>
<if test="nextFollowTime != null">#{nextFollowTime},</if> <if test="nextFollowTime != null">#{nextFollowTime},</if>
<if test="followTime != null">#{followTime},</if> <if test="followTime != null">#{followTime},</if>
<if test="customerStatus != null and customerStatus != ''">#{customerStatus},</if>
<if test="customerIntentLevel != null and customerIntentLevel != ''">#{customerIntentLevel},</if>
<if test="createTime != null">#{createTime},</if> <if test="createTime != null">#{createTime},</if>
</trim> </trim>
</insert> </insert>
@ -96,6 +104,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="data.userId != null">user_id = #{data.userId},</if> <if test="data.userId != null">user_id = #{data.userId},</if>
<if test="data.nextFollowTime != null">next_follow_time = #{data.nextFollowTime},</if> <if test="data.nextFollowTime != null">next_follow_time = #{data.nextFollowTime},</if>
<if test="data.followTime != null">follow_time = #{data.followTime},</if> <if test="data.followTime != null">follow_time = #{data.followTime},</if>
<if test="data.customerStatus != null and data.customerStatus != ''">customer_status = #{data.customerStatus},</if>
<if test="data.customerIntentLevel != null and data.customerIntentLevel != ''">customer_intent_level = #{data.customerIntentLevel},</if>
<if test="data.createTime != null">create_time = #{data.createTime},</if> <if test="data.createTime != null">create_time = #{data.createTime},</if>
</sql> </sql>

View File

@ -36,7 +36,7 @@ public interface CustomerFollowService
* @param customerFollow 客户跟进记录 * @param customerFollow 客户跟进记录
* @return 结果 * @return 结果
*/ */
public int insertCustomerFollow(CustomerFollow customerFollow); public int insertCustomerFollow(CustomerFollow dto);
/** /**
* 修改客户跟进记录 * 修改客户跟进记录
@ -44,7 +44,7 @@ public interface CustomerFollowService
* @param customerFollow 客户跟进记录 * @param customerFollow 客户跟进记录
* @return 结果 * @return 结果
*/ */
public int updateCustomerFollow(CustomerFollow customerFollow); public int updateCustomerFollow(CustomerFollow dto);
/** /**
* 批量删除客户跟进记录 * 批量删除客户跟进记录

View File

@ -6,6 +6,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import com.ruoyi.bst.customer.domain.Customer;
import com.ruoyi.bst.customer.domain.enums.CustomerStatus;
import com.ruoyi.bst.customer.service.CustomerConverter; import com.ruoyi.bst.customer.service.CustomerConverter;
import com.ruoyi.bst.customer.service.CustomerService; import com.ruoyi.bst.customer.service.CustomerService;
import com.ruoyi.bst.customerFollow.domain.CustomerFollow; import com.ruoyi.bst.customerFollow.domain.CustomerFollow;
@ -72,6 +74,8 @@ public class CustomerFollowServiceImpl implements CustomerFollowService
public int insertCustomerFollow(CustomerFollow data) public int insertCustomerFollow(CustomerFollow data)
{ {
ServiceUtil.assertion(data.getCustomerId() == null, "客户ID不能为空"); ServiceUtil.assertion(data.getCustomerId() == null, "客户ID不能为空");
ServiceUtil.assertion(data.getNextFollowTime() == null && !CustomerStatus.INVALID.getStatus().equals(data.getCustomerStatus()),
"非失效客户,必须填写下次跟进日期");
data.setUserId(SecurityUtils.getUserId()); data.setUserId(SecurityUtils.getUserId());
data.setCreateTime(DateUtils.getNowDate()); data.setCreateTime(DateUtils.getNowDate());
@ -81,8 +85,11 @@ public class CustomerFollowServiceImpl implements CustomerFollowService
int insert = customerFollowMapper.insertCustomerFollow(data); int insert = customerFollowMapper.insertCustomerFollow(data);
if (insert > 0) { if (insert > 0) {
// 更新客户状态
this.updateCustomerStatus(data);
// 更新客户最近跟进时间 // 更新客户最近跟进时间
customerService.updateFollowTime(data.getCustomerId(), data.getFollowTime()); this.updateFollowTime(data);
} }
return insert; return insert;
@ -103,8 +110,11 @@ public class CustomerFollowServiceImpl implements CustomerFollowService
int update = customerFollowMapper.updateCustomerFollow(data); int update = customerFollowMapper.updateCustomerFollow(data);
if (update > 0) { if (update > 0) {
// 更新客户状态
this.updateCustomerStatus(data);
// 更新客户最近跟进时间 // 更新客户最近跟进时间
customerService.updateFollowTime(data.getCustomerId(), data.getFollowTime()); this.updateFollowTime(data);
} }
return update; return update;
@ -112,6 +122,34 @@ public class CustomerFollowServiceImpl implements CustomerFollowService
return result == null ? 0 : result; return result == null ? 0 : result;
} }
/**
* 更新客户状态
*
* @param data 客户跟进记录
*/
private int updateCustomerStatus(CustomerFollow data) {
if (data.getCustomerId() != null && data.getCustomerStatus() != null) {
Customer customer = new Customer();
customer.setId(data.getCustomerId());
customer.setStatus(data.getCustomerStatus());
return customerService.updateCustomer(customer);
}
return 0;
}
/**
* 更新客户最近跟进时间
*
* @param data 客户跟进记录
*/
private int updateFollowTime(CustomerFollow data) {
if (data.getCustomerId() != null && data.getNextFollowTime() != null) {
// 更新客户最近跟进时间
return customerService.updateFollowTime(data.getCustomerId(), data.getNextFollowTime());
}
return 0;
}
/** /**
* 批量删除客户跟进记录 * 批量删除客户跟进记录
* *

View File

@ -51,4 +51,7 @@ public class ProjectQuery extends ProjectVO {
@ApiModelProperty("参与人ID") @ApiModelProperty("参与人ID")
private Long joinUserId; private Long joinUserId;
@ApiModelProperty("参与人ID列表")
private List<Long> joinUserIds;
} }

View File

@ -2,6 +2,7 @@ package com.ruoyi.bst.project.mapper;
import java.util.List; import java.util.List;
import com.ruoyi.common.vo.LongIntegerVO;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import com.ruoyi.bst.project.domain.Project; import com.ruoyi.bst.project.domain.Project;
@ -108,4 +109,11 @@ public interface ProjectMapper
* @return * @return
*/ */
List<IntegerIntegerVO> selectCountGroupByStartMonth(@Param("query") ProjectQuery query); List<IntegerIntegerVO> selectCountGroupByStartMonth(@Param("query") ProjectQuery query);
/**
* 按参与人ID分组查询数量
* @param query
* @return
*/
List<LongIntegerVO> selectCountGroupByMemberUserId(@Param("query") ProjectQuery query);
} }

View File

@ -250,7 +250,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<!-- selectCountGroupByCreateMonth --> <!-- selectCountGroupByCreateMonth -->
<select id="selectCountGroupByCreateMonth"> <select id="selectCountGroupByCreateMonth" resultMap="com.ruoyi.common.mapper.CommonMapper.IntegerIntegerVO">
select select
month(bp.create_time) as `key`, month(bp.create_time) as `key`,
count(distinct bp.id) as `value` count(distinct bp.id) as `value`
@ -263,7 +263,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<!-- selectCountGroupByCompleteMonth --> <!-- selectCountGroupByCompleteMonth -->
<select id="selectCountGroupByCompleteMonth"> <select id="selectCountGroupByCompleteMonth" resultMap="com.ruoyi.common.mapper.CommonMapper.IntegerIntegerVO">
select select
month(bp.complete_time) as `key`, month(bp.complete_time) as `key`,
count(distinct bp.id) as `value` count(distinct bp.id) as `value`
@ -276,7 +276,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<!-- selectCountGroupByStartMonth --> <!-- selectCountGroupByStartMonth -->
<select id="selectCountGroupByStartMonth"> <select id="selectCountGroupByStartMonth" resultMap="com.ruoyi.common.mapper.CommonMapper.IntegerIntegerVO">
select select
month(bp.start_time) as `key`, month(bp.start_time) as `key`,
count(distinct bp.id) as `value` count(distinct bp.id) as `value`
@ -287,4 +287,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
group by `key` group by `key`
</select> </select>
<!-- selectCountGroupByMemberUserId -->
<select id="selectCountGroupByMemberUserId" resultMap="com.ruoyi.common.mapper.CommonMapper.LongIntegerVO">
select
bpm.user_id as `key`,
count(distinct bp.id) as `value`
<include refid="searchTables"/>
<where>
<include refid="searchCondition"/>
</where>
group by `key`
</select>
</mapper> </mapper>

View File

@ -15,6 +15,9 @@ public class TaskQuery extends TaskVO{
@ApiModelProperty("负责人ID") @ApiModelProperty("负责人ID")
private Long ownerId; private Long ownerId;
@ApiModelProperty("负责人ID列表")
private List<Long> ownerIds;
@ApiModelProperty("项目id列表") @ApiModelProperty("项目id列表")
private List<Long> projectIds; private List<Long> projectIds;

View File

@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Param;
import com.ruoyi.bst.task.domain.Task; import com.ruoyi.bst.task.domain.Task;
import com.ruoyi.bst.task.domain.TaskQuery; import com.ruoyi.bst.task.domain.TaskQuery;
import com.ruoyi.bst.task.domain.TaskVO; import com.ruoyi.bst.task.domain.TaskVO;
import com.ruoyi.common.vo.IntegerIntegerVO;
import com.ruoyi.common.vo.LongIntegerVO; import com.ruoyi.common.vo.LongIntegerVO;
import com.ruoyi.common.vo.StringIntegerVO; import com.ruoyi.common.vo.StringIntegerVO;
@ -93,4 +94,11 @@ public interface TaskMapper
* @return * @return
*/ */
List<StringIntegerVO> selectCountGroupByType(@Param("query") TaskQuery query); List<StringIntegerVO> selectCountGroupByType(@Param("query") TaskQuery query);
/**
* 查询参与人任务数并按参与人ID分组
* @param query
* @return
*/
List<LongIntegerVO> selectCountGroupByMemberUserId(@Param("query") TaskQuery query);
} }

View File

@ -245,4 +245,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
group by `key` group by `key`
</select> </select>
<!-- selectCountGroupByMemberUserId -->
<select id="selectCountGroupByMemberUserId" parameterType="TaskQuery" resultMap="com.ruoyi.common.mapper.CommonMapper.LongIntegerVO">
select
btm.user_id as `key`,
count(distinct bt.id) as `value`
<include refid="searchTables"/>
<where>
<include refid="searchCondition"/>
</where>
group by `key`
</select>
</mapper> </mapper>

View File

@ -18,6 +18,11 @@
<result property="value" column="value" typeHandler="com.ruoyi.common.mybatis.typehandler.NonNullIntegerTyperHandler"/> <result property="value" column="value" typeHandler="com.ruoyi.common.mybatis.typehandler.NonNullIntegerTyperHandler"/>
</resultMap> </resultMap>
<resultMap id="IntegerIntegerVO" type="com.ruoyi.common.vo.IntegerIntegerVO">
<result property="key" column="key"/>
<result property="value" column="value" typeHandler="com.ruoyi.common.mybatis.typehandler.NonNullIntegerTyperHandler"/>
</resultMap>
<resultMap id="LocalDateIntegerVO" type="com.ruoyi.common.vo.LocalDateIntegerVO"> <resultMap id="LocalDateIntegerVO" type="com.ruoyi.common.vo.LocalDateIntegerVO">
<result property="key" column="key"/> <result property="key" column="key"/>
<result property="value" column="value" typeHandler="com.ruoyi.common.mybatis.typehandler.NonNullIntegerTyperHandler"/> <result property="value" column="value" typeHandler="com.ruoyi.common.mybatis.typehandler.NonNullIntegerTyperHandler"/>

View File

@ -0,0 +1,14 @@
package com.ruoyi.dashboard.customer.domain.brief;
import java.util.List;
import com.ruoyi.bst.customer.domain.CustomerQuery;
import lombok.Data;
@Data
public class CustomerBriefQuery extends CustomerQuery {
private List<String> keys;
}

View File

@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import com.ruoyi.common.vo.LongIntegerVO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -167,4 +168,9 @@ public class DashboardProjectService {
return this.selectCount(query); return this.selectCount(query);
} }
// 查询参与人项目数并按参与人ID分组
public List<LongIntegerVO> selectCountGroupByMemberUserId(ProjectQuery query) {
return projectMapper.selectCountGroupByMemberUserId(query);
}
} }

View File

@ -0,0 +1,14 @@
package com.ruoyi.dashboard.task.domain.brief;
import java.util.List;
import com.ruoyi.bst.task.domain.TaskQuery;
import lombok.Data;
@Data
public class TaskBriefQuery extends TaskQuery {
private List<String> keys;
}

View File

@ -4,13 +4,16 @@ import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import com.ruoyi.common.vo.LongIntegerVO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.bst.task.domain.TaskQuery; import com.ruoyi.bst.task.domain.TaskQuery;
import com.ruoyi.bst.task.domain.enums.TaskStatus; import com.ruoyi.bst.task.domain.enums.TaskStatus;
import com.ruoyi.bst.task.mapper.TaskMapper;
import com.ruoyi.bst.task.service.TaskService; import com.ruoyi.bst.task.service.TaskService;
import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.vo.IntegerIntegerVO;
import com.ruoyi.common.vo.StringIntegerVO; import com.ruoyi.common.vo.StringIntegerVO;
import com.ruoyi.dashboard.index.domain.brief.BriefKeys; import com.ruoyi.dashboard.index.domain.brief.BriefKeys;
import com.ruoyi.dashboard.index.domain.brief.TaskBriefVO; import com.ruoyi.dashboard.index.domain.brief.TaskBriefVO;
@ -20,6 +23,9 @@ public class DashboardTaskService {
@Autowired @Autowired
private TaskService taskService; private TaskService taskService;
@Autowired
private TaskMapper taskMapper;
public TaskBriefVO selectTaskBrief(TaskQuery query, List<String> keyList) { public TaskBriefVO selectTaskBrief(TaskQuery query, List<String> keyList) {
TaskBriefVO vo = new TaskBriefVO(); TaskBriefVO vo = new TaskBriefVO();
if (keyList != null) { if (keyList != null) {
@ -99,4 +105,9 @@ public class DashboardTaskService {
query.setOverdue(true); query.setOverdue(true);
return taskService.selectCount(query); return taskService.selectCount(query);
} }
// 查询参与人任务数并按参与人ID分组
public List<LongIntegerVO> selectCountGroupByMemberUserId(TaskQuery query) {
return taskMapper.selectCountGroupByMemberUserId(query);
}
} }

View File

@ -1,11 +1,17 @@
package com.ruoyi.system.user.service.impl; package com.ruoyi.system.user.service.impl;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.ruoyi.common.vo.LongIntegerVO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.bst.project.domain.ProjectQuery;
import com.ruoyi.bst.task.domain.TaskQuery;
import com.ruoyi.common.utils.collection.CollectionUtils; import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.common.vo.IntegerIntegerVO;
import com.ruoyi.dashboard.project.service.DashboardProjectService; import com.ruoyi.dashboard.project.service.DashboardProjectService;
import com.ruoyi.dashboard.task.service.DashboardTaskService; import com.ruoyi.dashboard.task.service.DashboardTaskService;
import com.ruoyi.system.user.domain.SysUserVO; import com.ruoyi.system.user.domain.SysUserVO;
@ -25,16 +31,42 @@ public class UserAssemblerImpl implements UserAssembler{
if (CollectionUtils.isEmptyElement(list)) { if (CollectionUtils.isEmptyElement(list)) {
return; return;
} }
// ProjectQuery query = new ProjectQuery(); ProjectQuery query = new ProjectQuery();
// query.setUserIds(list.stream().map(SysUserVO::getUserId).collect(Collectors.toList())); query.setJoinUserIds(list.stream().map(SysUserVO::getUserId).collect(Collectors.toList()));
// dashboardProjectService.selectCountGroupByUserId(query); List<LongIntegerVO> result = dashboardProjectService.selectCountGroupByMemberUserId(query);
for (SysUserVO user : list) {
LongIntegerVO vo = result.stream()
.filter(item -> Objects.equals(item.getKey(), user.getUserId()))
.findFirst()
.orElse(null);
if (vo != null) {
user.setProjectCount(vo.getValue());
} else {
user.setProjectCount(0);
}
}
} }
@Override @Override
public void assembleTaskCount(List<SysUserVO> list) { public void assembleTaskCount(List<SysUserVO> list) {
// TODO Auto-generated method stub if (CollectionUtils.isEmptyElement(list)) {
// throw new UnsupportedOperationException("Unimplemented method 'assembleTaskCount'"); return;
}
TaskQuery query = new TaskQuery();
query.setOwnerIds(list.stream().map(SysUserVO::getUserId).collect(Collectors.toList()));
List<LongIntegerVO> result = dashboardTaskService.selectCountGroupByMemberUserId(query);
for (SysUserVO user : list) {
LongIntegerVO vo = result.stream()
.filter(item -> Objects.equals(item.getKey(), user.getUserId()))
.findFirst()
.orElse(null);
if (vo != null) {
user.setTaskCount(vo.getValue());
} else {
user.setTaskCount(0);
}
}
} }
} }

View File

@ -141,4 +141,5 @@ public class CustomerController extends BaseController
{ {
return toAjax(customerService.logicDel(ids)); return toAjax(customerService.logicDel(ids));
} }
} }

View File

@ -4,6 +4,7 @@ import java.util.List;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.ruoyi.bst.customerFollow.domain.CustomerFollow;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -16,7 +17,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.bst.customerFollow.domain.CustomerFollow;
import com.ruoyi.bst.customerFollow.domain.CustomerFollowQuery; import com.ruoyi.bst.customerFollow.domain.CustomerFollowQuery;
import com.ruoyi.bst.customerFollow.domain.CustomerFollowVO; import com.ruoyi.bst.customerFollow.domain.CustomerFollowVO;
import com.ruoyi.bst.customerFollow.service.CustomerFollowService; import com.ruoyi.bst.customerFollow.service.CustomerFollowService;
@ -84,9 +84,9 @@ public class CustomerFollowController extends BaseController
@PreAuthorize("@ss.hasPermi('bst:customerFollow:add')") @PreAuthorize("@ss.hasPermi('bst:customerFollow:add')")
@Log(title = "客户跟进记录", businessType = BusinessType.INSERT) @Log(title = "客户跟进记录", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@RequestBody @Validated(ValidGroup.Create.class) CustomerFollow customerFollow) public AjaxResult add(@RequestBody @Validated(ValidGroup.Create.class) CustomerFollow dto)
{ {
return toAjax(customerFollowService.insertCustomerFollow(customerFollow)); return toAjax(customerFollowService.insertCustomerFollow(dto));
} }
/** /**
@ -95,9 +95,9 @@ public class CustomerFollowController extends BaseController
@PreAuthorize("@ss.hasPermi('bst:customerFollow:edit')") @PreAuthorize("@ss.hasPermi('bst:customerFollow:edit')")
@Log(title = "客户跟进记录", businessType = BusinessType.UPDATE) @Log(title = "客户跟进记录", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@RequestBody @Validated(ValidGroup.Update.class) CustomerFollow customerFollow) public AjaxResult edit(@RequestBody @Validated(ValidGroup.Update.class) CustomerFollow dto)
{ {
return toAjax(customerFollowService.updateCustomerFollow(customerFollow)); return toAjax(customerFollowService.updateCustomerFollow(dto));
} }
/** /**

View File

@ -3,6 +3,7 @@ package com.ruoyi.web.dashboard;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -13,6 +14,7 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.collection.CollectionUtils; import com.ruoyi.common.utils.collection.CollectionUtils;
import com.ruoyi.common.vo.LocalDateIntegerVO; import com.ruoyi.common.vo.LocalDateIntegerVO;
import com.ruoyi.dashboard.customer.domain.brief.CustomerBriefQuery;
import com.ruoyi.dashboard.customer.service.DashboardCustomerService; import com.ruoyi.dashboard.customer.service.DashboardCustomerService;
@RestController @RestController
@ -42,4 +44,12 @@ public class DashboardCustomerController extends BaseController {
return success(list); return success(list);
} }
// 客户概览
@GetMapping("/brief")
@PreAuthorize("@ss.hasPermi('dashboard:brief')")
public AjaxResult brief(CustomerBriefQuery query) {
query.setScope(true);
return success(dashboardCustomerService.selectCustomerBrief(query, query.getKeys()));
}
} }

View File

@ -1,10 +1,14 @@
package com.ruoyi.web.dashboard; package com.ruoyi.web.dashboard;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.dashboard.task.domain.brief.TaskBriefQuery;
import com.ruoyi.dashboard.task.service.DashboardTaskService; import com.ruoyi.dashboard.task.service.DashboardTaskService;
@ -15,4 +19,11 @@ public class DashboardTaskController extends BaseController {
@Autowired @Autowired
private DashboardTaskService dashboardTaskService; private DashboardTaskService dashboardTaskService;
@GetMapping("/brief")
@PreAuthorize("@ss.hasPermi('dashboard:brief')")
public AjaxResult brief(TaskBriefQuery query) {
query.setScope(true);
return success(dashboardTaskService.selectTaskBrief(query, query.getKeys()));
}
} }