Merge #37 into master from cc_20251208_visit
feat:拜访字段调整
* cc_20251208_visit: (19 commits squashed)
- feat:拜访记录
- fix:拜访详情接口新增字段
- fix:新增状态转义字段
- fix:惩处单查询提供惩处待处理、惩处已处理状态筛选
- fix
- fix:管理员能查看所有加盟商
- fix:去掉部分字段非空校验
- fix:空校验
- Merge branch 'master' into cc_20251208_visit
# Conflicts:
#	coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java
#	coolstore-partner-dao/src/main/java/com/cool/store/dao/store/StoreMasterSignerInfoDAO.java
#	coolstore-partner-service/src/main/java/com/cool/store/service/impl/UserAuthMappingServiceImpl.java
- fix
- fix:拜访记录失效延时消息
- fix:拜访记录统计
- fix:拜访记录统计新增筛选条件
- fix:字段转义
- feat:拜访调整
- feat:拜访调整_过滤我的
- feat:拜访调整_过滤我的
- feat:拜访字段调整
- feat:拜访字段调整
Signed-off-by: 正新 <accounts_6964c7bcd2a2c377c5bbd01b@mail.teambition.com>
Merged-by: 正新 <accounts_6964c7bcd2a2c377c5bbd01b@mail.teambition.com>
CR-link: https://codeup.aliyun.com/692ea314dec569489f6f167c/hangzhou/java/custom_zxjp/change/37
This commit is contained in:
@@ -373,6 +373,11 @@ public enum ErrorCodeEnum {
|
||||
TP_EXIST_PENDING_IMPORT_TASK(1810012, "存在导入中的任务,请稍后再试", null),
|
||||
TP_NOT_EXIST_FORM_TYPE(1810013, "不存在该表单类型", null),
|
||||
|
||||
VISIT_RECORD_NOT_EXIST(1820001, "拜访记录不存在", null),
|
||||
VISIT_RECORD_NOT_COMPLETE_EDIT(1820002, "未编辑拜访信息,无法签退", null),
|
||||
VISIT_RECORD_INVALID(1820003, "拜访记录已失效", null),
|
||||
VISIT_RECORD_NOT_YOUR_OWN(1820004, "非拜访人,无法操作", null),
|
||||
VISIT_RECORD_COMPLETE(1820005, "已完成拜访", null),
|
||||
CITY_PLANNING_EXISTS(1820001, "同年份同季度同省市已存在规划,不能重复添加", null),
|
||||
;
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public enum RocketMqGroupEnum {
|
||||
SHOP_DECORATION_ASSIGN("shop_decoration_assign", new ArrayList<>(Arrays.asList(RocketMqTagEnum.DELAY_SHOP_DECORATION_ASSIGN))),
|
||||
|
||||
STORE_MASTER_ISSUE("store_master_issue", new ArrayList<>(Arrays.asList(RocketMqTagEnum.STORE_MASTER_ISSUE))),
|
||||
|
||||
VISIT_RECORD_INVALID("visit_record_invalid", new ArrayList<>(Arrays.asList(RocketMqTagEnum.VISIT_RECORD_INVALID))),
|
||||
;
|
||||
|
||||
private final String group;
|
||||
|
||||
@@ -21,6 +21,7 @@ public enum RocketMqTagEnum {
|
||||
STORE_USER_UPDATE("store_user_update", "门店信息人员变更同步菜品"),
|
||||
DELAY_SHOP_DECORATION_ASSIGN("shop_decoration_assign","门店装修分配"),
|
||||
STORE_MASTER_ISSUE("store_master_issue","门店主数据下发"),
|
||||
VISIT_RECORD_INVALID("visit_record_invalid", "拜访记录失效"),
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.cool.store.enums.visit;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录状态枚举类
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/8
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum VisitStatusEnum {
|
||||
|
||||
N_SIGN_IN(0, "待签到"),
|
||||
|
||||
N_SIGN_OUT(1, "待签退"),
|
||||
|
||||
COMPLETE(2, "已完成"),
|
||||
|
||||
INVALID(3, "已失效"),
|
||||
;
|
||||
|
||||
private final Integer status;
|
||||
|
||||
private final String desc;
|
||||
|
||||
public static String getDescByStatus(Integer status) {
|
||||
for (VisitStatusEnum value : values()) {
|
||||
if (value.status.equals(status)) {
|
||||
return value.desc;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,9 @@ import com.cool.store.mapper.store.StoreMasterSignerInfoMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import tk.mybatis.mapper.entity.Example;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -41,4 +43,15 @@ public class StoreMasterSignerInfoDAO {
|
||||
public StoreMasterSignerInfoDO getByStoreId(String storeId) {
|
||||
return storeMasterSignerInfoMapper.selectOne(StoreMasterSignerInfoDO.builder().storeId(storeId).build());
|
||||
}
|
||||
|
||||
public List<StoreMasterSignerInfoDO> getListByIdCard(Collection<String> idCards) {
|
||||
if (CollectionUtils.isEmpty(idCards)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Example example = new Example(StoreMasterSignerInfoDO.class);
|
||||
example.createCriteria()
|
||||
.orIn("signer1IdCardNo", idCards)
|
||||
.orIn("signer2IdCardNo", idCards);
|
||||
return storeMasterSignerInfoMapper.selectByExample(example);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.cool.store.dao.visit;
|
||||
|
||||
import com.alibaba.excel.util.CollectionUtils;
|
||||
import com.cool.store.entity.visit.VisitRecordDO;
|
||||
import com.cool.store.enums.visit.VisitStatusEnum;
|
||||
import com.cool.store.mapper.visit.VisitRecordMapper;
|
||||
import com.cool.store.request.visit.VisitRecordQueryRequest;
|
||||
import com.cool.store.vo.visit.VisitPartnerListVO;
|
||||
import com.cool.store.vo.visit.VisitRecordListVO;
|
||||
import com.cool.store.vo.visit.VisitRecordStatusStatisticsVO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import tk.mybatis.mapper.entity.Example;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录DAO
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/8
|
||||
*/
|
||||
@Repository
|
||||
@AllArgsConstructor
|
||||
public class VisitRecordDAO {
|
||||
private final VisitRecordMapper visitRecordMapper;
|
||||
|
||||
public Boolean insertSelective(VisitRecordDO visitRecordDO) {
|
||||
return visitRecordMapper.insertSelective(visitRecordDO) > 0;
|
||||
}
|
||||
|
||||
public Boolean updateSelective(VisitRecordDO visitRecordDO) {
|
||||
return visitRecordMapper.updateByPrimaryKeySelective(visitRecordDO) > 0;
|
||||
}
|
||||
|
||||
public VisitRecordDO getById(Long id) {
|
||||
return visitRecordMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询拜访加盟商
|
||||
* @param regionIds 加盟商所属大区id
|
||||
* @param keyword 加盟商姓名或手机号
|
||||
* @return 拜访加盟商列表VO
|
||||
*/
|
||||
public List<VisitPartnerListVO> getPartnerList(List<Long> regionIds, String keyword, String userId) {
|
||||
return visitRecordMapper.getPartnerList(regionIds, keyword, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询拜访加盟商线索id
|
||||
* @param regionIds 加盟商所属大区id
|
||||
* @param keyword 加盟商姓名或手机号
|
||||
* @param userId 拜访用户id
|
||||
* @return 线索id列表
|
||||
*/
|
||||
public List<Long> getPartnerLineId(List<Long> regionIds, String keyword, String userId) {
|
||||
return visitRecordMapper.getPartnerLineId(regionIds, keyword, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据线索id查询拜访记录列表
|
||||
* @param lineIds 线索id
|
||||
* @return 拜访记录列表VO列表
|
||||
*/
|
||||
public List<VisitPartnerListVO> getVisitRecordListByLineIds(List<Long> lineIds, String userId) {
|
||||
if (CollectionUtils.isEmpty(lineIds)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return visitRecordMapper.getVisitRecordListByLineIds(lineIds, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据线索查询
|
||||
* @param lineId 线索id
|
||||
* @param startDate 开始日期
|
||||
* @param endDate 结束日期
|
||||
* @return 拜访记录列表
|
||||
*/
|
||||
public List<VisitRecordDO> getByLineId(Long lineId, Date startDate, Date endDate, String userId) {
|
||||
Example example = new Example(VisitRecordDO.class);
|
||||
Example.Criteria criteria = example.createCriteria().andEqualTo("lineId", lineId)
|
||||
.andGreaterThanOrEqualTo("visitDate", startDate)
|
||||
.andLessThanOrEqualTo("visitDate", endDate);
|
||||
if (StringUtils.isNotBlank(userId)) {
|
||||
criteria.andEqualTo("userId", userId);
|
||||
}
|
||||
example.setOrderByClause("create_time DESC");
|
||||
return visitRecordMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public Boolean deleteById(Long id) {
|
||||
return visitRecordMapper.deleteByPrimaryKey(id) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 拜访记录列表
|
||||
* @param request 拜访记录查询Request
|
||||
* @return 拜访记录列表VO列表
|
||||
*/
|
||||
public List<VisitRecordListVO> getVisitRecordList(VisitRecordQueryRequest request) {
|
||||
return visitRecordMapper.getVisitRecordList(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据线索id查询已完成拜访数量
|
||||
* @param lineId 线索id
|
||||
* @return 数量
|
||||
*/
|
||||
public Integer getCompleteVisitNum(Long lineId) {
|
||||
return visitRecordMapper.selectCount(VisitRecordDO.builder().lineId(lineId).status(VisitStatusEnum.COMPLETE.getStatus()).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计
|
||||
*/
|
||||
public VisitRecordStatusStatisticsVO countStatusStatistics(VisitRecordQueryRequest request) {
|
||||
return visitRecordMapper.countStatusStatistics(request);
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,8 @@ public interface RegionMapper {
|
||||
|
||||
List<String> getSubRegionIdsByRegionIds( @Param("regionIds")List<String> regionIds);
|
||||
|
||||
List<String> getSubRegionIdsExcludeStore(@Param("regionIds")List<String> regionIds);
|
||||
|
||||
List<Long> getSubRegionIdsByRegionIdList( @Param("regionIds")List<Long> regionIds);
|
||||
|
||||
List<String> getStoreIdsByRegionIds( @Param("regionIds")List<String> regionIds);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.cool.store.mapper.oplog;
|
||||
|
||||
import com.cool.store.entity.oplog.SysLogDO;
|
||||
import tk.mybatis.mapper.common.Mapper;
|
||||
|
||||
public interface SysLogMapper extends Mapper<SysLogDO> {
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.cool.store.mapper.visit;
|
||||
|
||||
import com.cool.store.entity.visit.VisitRecordDO;
|
||||
import com.cool.store.request.visit.VisitRecordQueryRequest;
|
||||
import com.cool.store.vo.visit.VisitPartnerListVO;
|
||||
import com.cool.store.vo.visit.VisitRecordListVO;
|
||||
import com.cool.store.vo.visit.VisitRecordStatusStatisticsVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import tk.mybatis.mapper.common.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface VisitRecordMapper extends Mapper<VisitRecordDO> {
|
||||
|
||||
/**
|
||||
* 查询拜访加盟商
|
||||
* @param regionIds 加盟商所属大区id
|
||||
* @param keyword 加盟商姓名或手机号
|
||||
* @return 拜访加盟商列表VO
|
||||
*/
|
||||
List<VisitPartnerListVO> getPartnerList(@Param("regionIds") List<Long> regionIds,
|
||||
@Param("keyword") String keyword,
|
||||
@Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* 拜访记录列表
|
||||
* @param request 拜访记录查询Request
|
||||
* @return 拜访记录列表VO列表
|
||||
*/
|
||||
List<VisitRecordListVO> getVisitRecordList(@Param("request") VisitRecordQueryRequest request);
|
||||
|
||||
/**
|
||||
* 查询拜访加盟商线索id
|
||||
* @param regionIds 加盟商所属大区id
|
||||
* @param keyword 加盟商姓名或手机号
|
||||
* @param userId 拜访用户id
|
||||
* @return 线索id列表
|
||||
*/
|
||||
List<Long> getPartnerLineId(@Param("regionIds") List<Long> regionIds,
|
||||
@Param("keyword") String keyword,
|
||||
@Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* 根据线索id查询拜访记录列表
|
||||
* @param lineIds 线索id
|
||||
* @return 拜访记录列表VO列表
|
||||
*/
|
||||
List<VisitPartnerListVO> getVisitRecordListByLineIds(@Param("lineIds") List<Long> lineIds, @Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* 统计:本月已完成数量、全部已完成数量、全部未完成数量、全部已失效数量
|
||||
* - 本月口径:按 visit_date 在本月范围内且 status=2
|
||||
* - 全部口径:不限制月份
|
||||
*/
|
||||
VisitRecordStatusStatisticsVO countStatusStatistics(@Param("request") VisitRecordQueryRequest request);
|
||||
|
||||
}
|
||||
@@ -285,6 +285,17 @@
|
||||
<foreach collection="regionIds" separator=" or " open="(" close=")" item="region" > region_path like concat("%/", #{region}, "/%")</foreach>
|
||||
</select>
|
||||
|
||||
<select id="getSubRegionIdsExcludeStore" resultType="string">
|
||||
select
|
||||
id
|
||||
from
|
||||
region_${enterpriseId}
|
||||
where
|
||||
deleted = 0 and region_type != 'store'
|
||||
and
|
||||
<foreach collection="regionIds" separator=" or " open="(" close=")" item="region" > region_path like concat("%/", #{region}, "/%")</foreach>
|
||||
</select>
|
||||
|
||||
<select id="getStoreIdsByRegionIds" resultType="string">
|
||||
select
|
||||
store_id
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.cool.store.mapper.oplog.SysLogMapper">
|
||||
<resultMap id="BaseResultMap" type="com.cool.store.entity.oplog.SysLogDO">
|
||||
<!--
|
||||
WARNING - @mbg.generated
|
||||
-->
|
||||
<id column="id" jdbcType="BIGINT" property="id" />
|
||||
<result column="menus" jdbcType="VARCHAR" property="menus" />
|
||||
<result column="module" jdbcType="VARCHAR" property="module" />
|
||||
<result column="func" jdbcType="VARCHAR" property="func" />
|
||||
<result column="sub_func" jdbcType="VARCHAR" property="subFunc" />
|
||||
<result column="op_user_id" jdbcType="VARCHAR" property="opUserId" />
|
||||
<result column="op_user_name" jdbcType="VARCHAR" property="opUserName" />
|
||||
<result column="op_user_mobile" jdbcType="VARCHAR" property="opUserMobile" />
|
||||
<result column="op_time" jdbcType="TIMESTAMP" property="opTime" />
|
||||
<result column="op_type" jdbcType="VARCHAR" property="opType" />
|
||||
<result column="op_content" jdbcType="VARCHAR" property="opContent" />
|
||||
<result column="op_ip" jdbcType="VARCHAR" property="opIp" />
|
||||
<result column="device_info" jdbcType="VARCHAR" property="deviceInfo" />
|
||||
<result column="req_params" jdbcType="VARCHAR" property="reqParams" />
|
||||
<result column="resp_params" jdbcType="VARCHAR" property="respParams" />
|
||||
<result column="url" jdbcType="VARCHAR" property="url" />
|
||||
<result column="extend_info" jdbcType="VARCHAR" property="extendInfo" />
|
||||
<result column="op_user_jobnumber" jdbcType="LONGVARCHAR" property="opUserJobnumber" />
|
||||
</resultMap>
|
||||
</mapper>
|
||||
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.cool.store.mapper.visit.VisitRecordMapper">
|
||||
<resultMap id="BaseResultMap" type="com.cool.store.entity.visit.VisitRecordDO">
|
||||
<!--
|
||||
WARNING - @mbg.generated
|
||||
-->
|
||||
<id column="id" jdbcType="BIGINT" property="id" />
|
||||
<result column="visit_no" jdbcType="VARCHAR" property="visitNo" />
|
||||
<result column="line_id" jdbcType="BIGINT" property="lineId" />
|
||||
<result column="status" jdbcType="BIT" property="status" />
|
||||
<result column="complete_edit" jdbcType="BIT" property="completeEdit" />
|
||||
<result column="sign_in_time" jdbcType="TIMESTAMP" property="signInTime" />
|
||||
<result column="sign_in_lon_lat" jdbcType="VARCHAR" property="signInLonLat" />
|
||||
<result column="sign_in_address" jdbcType="VARCHAR" property="signInAddress" />
|
||||
<result column="sign_out_time" jdbcType="TIMESTAMP" property="signOutTime" />
|
||||
<result column="sign_out_lon_lat" jdbcType="VARCHAR" property="signOutLonLat" />
|
||||
<result column="sign_out_address" jdbcType="VARCHAR" property="signOutAddress" />
|
||||
<result column="visit_date" jdbcType="DATE" property="visitDate" />
|
||||
<result column="desire" jdbcType="VARCHAR" property="desire" />
|
||||
<result column="desire_city" jdbcType="VARCHAR" property="desireCity" />
|
||||
<result column="desire_district" jdbcType="VARCHAR" property="desireDistrict" />
|
||||
<result column="existing_shop_point" jdbcType="BIT" property="existingShopPoint" />
|
||||
<result column="remark" jdbcType="VARCHAR" property="remark" />
|
||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
|
||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
|
||||
<result column="photos" jdbcType="LONGVARCHAR" property="photos" />
|
||||
<result column="user_id" jdbcType="VARCHAR" property="userId" />
|
||||
</resultMap>
|
||||
|
||||
<select id="getPartnerList" resultType="com.cool.store.vo.visit.VisitPartnerListVO">
|
||||
SELECT a.line_id, a.visit_num, b.username name, b.mobile
|
||||
<if test="userId != null and userId != ''">
|
||||
, a.my_visit_num
|
||||
</if>
|
||||
FROM (
|
||||
SELECT line_id, COUNT(1) visit_num
|
||||
<if test="userId != null and userId != ''">
|
||||
, SUM(CASE WHEN user_id = #{userId} THEN 1 ELSE 0 END) my_visit_num
|
||||
</if>
|
||||
FROM zxjp_visit_record
|
||||
WHERE status = 2
|
||||
GROUP BY line_id
|
||||
) a
|
||||
INNER JOIN xfsg_line_info b ON a.line_id = b.id AND b.deleted = 0
|
||||
<where>
|
||||
<if test="userId != null and userId != ''">
|
||||
AND a.my_visit_num > 0
|
||||
</if>
|
||||
<if test="regionIds != null and !regionIds.isEmpty()">
|
||||
AND b.region_id IN
|
||||
<foreach item="regionId" collection="regionIds" separator="," open="(" close=")">
|
||||
#{regionId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="keyword != null and keyword != ''">
|
||||
AND (b.mobile LIKE CONCAT('%', #{keyword}, '%') OR b.username LIKE CONCAT('%', #{keyword}, '%'))
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getVisitRecordList" resultType="com.cool.store.vo.visit.VisitRecordListVO">
|
||||
SELECT a.id, a.line_id, a.visit_no, a.visit_date, a.sign_in_address, a.desire, a.desire_city,
|
||||
a.desire_district, a.existing_shop_point, a.photos, a.status,
|
||||
b.username name, b.mobile,a.user_id as visitUserId
|
||||
FROM zxjp_visit_record a
|
||||
INNER JOIN xfsg_line_info b ON a.line_id = b.id AND b.deleted = 0
|
||||
<where>
|
||||
<if test="request.visitUserId!=null and request.visitUserId!=''">
|
||||
and a.user_id = #{request.visitUserId}
|
||||
</if>
|
||||
<if test="request.lineId != null">
|
||||
AND a.line_id = #{request.lineId}
|
||||
</if>
|
||||
<if test="request.keyword != null and request.keyword != ''">
|
||||
AND (b.mobile LIKE CONCAT('%', #{request.keyword}, '%') OR b.username LIKE CONCAT('%', #{request.keyword}, '%'))
|
||||
</if>
|
||||
<if test="request.visitNo != null and request.visitNo != ''">
|
||||
AND a.visit_no LIKE CONCAT('%', #{request.visitNo}, '%')
|
||||
</if>
|
||||
<if test="request.visitStartDate != null">
|
||||
AND a.visit_date >= #{request.visitStartDate}
|
||||
</if>
|
||||
<if test="request.visitEndDate != null">
|
||||
AND a.visit_date <= #{request.visitEndDate}
|
||||
</if>
|
||||
<if test="request.status != null">
|
||||
AND a.status = #{request.status}
|
||||
</if>
|
||||
<if test="request.userId != null">
|
||||
AND a.user_id = #{request.userId}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY a.create_time DESC
|
||||
</select>
|
||||
|
||||
<select id="getPartnerLineId" resultType="java.lang.Long">
|
||||
SELECT DISTINCT a.line_id
|
||||
FROM zxjp_visit_record a
|
||||
INNER JOIN xfsg_line_info b ON a.line_id = b.id AND b.deleted = 0
|
||||
<where>
|
||||
<if test="userId != null and userId != ''">
|
||||
AND a.user_id = #{userId}
|
||||
</if>
|
||||
<if test="regionIds != null and !regionIds.isEmpty()">
|
||||
AND b.region_id IN
|
||||
<foreach item="regionId" collection="regionIds" separator="," open="(" close=")">
|
||||
#{regionId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="keyword != null and keyword != ''">
|
||||
AND (b.mobile LIKE CONCAT('%', #{keyword}, '%') OR b.username LIKE CONCAT('%', #{keyword}, '%'))
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getVisitRecordListByLineIds" resultType="com.cool.store.vo.visit.VisitPartnerListVO">
|
||||
SELECT line_id, SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) visit_num
|
||||
<if test="userId != null and userId != ''">
|
||||
, SUM(CASE WHEN user_id = #{userId} AND status = 2 THEN 1 ELSE 0 END) my_visit_num
|
||||
</if>
|
||||
FROM zxjp_visit_record
|
||||
WHERE line_id IN
|
||||
<foreach item="lineId" collection="lineIds" separator="," open="(" close=")">
|
||||
#{lineId}
|
||||
</foreach>
|
||||
GROUP BY line_id
|
||||
</select>
|
||||
|
||||
<select id="countStatusStatistics" resultType="com.cool.store.vo.visit.VisitRecordStatusStatisticsVO">
|
||||
SELECT
|
||||
SUM(CASE
|
||||
WHEN a.status = 2
|
||||
AND a.visit_date >= DATE_FORMAT(CURDATE(), '%Y-%m-01')
|
||||
AND a.visit_date < DATE_ADD(DATE_FORMAT(CURDATE(), '%Y-%m-01'), INTERVAL 1 MONTH)
|
||||
THEN 1 ELSE 0
|
||||
END) AS monthCompletedCount,
|
||||
SUM(CASE WHEN a.status = 2 THEN 1 ELSE 0 END) AS completedCount,
|
||||
SUM(CASE WHEN a.status IN (0, 1) THEN 1 ELSE 0 END) AS uncompletedCount,
|
||||
SUM(CASE WHEN a.status = 3 THEN 1 ELSE 0 END) AS invalidCount
|
||||
FROM zxjp_visit_record a
|
||||
INNER JOIN xfsg_line_info b ON a.line_id = b.id AND b.deleted = 0
|
||||
<where>
|
||||
<if test="request.visitUserId!=null and request.visitUserId!=''">
|
||||
and a.user_id = #{request.visitUserId}
|
||||
</if>
|
||||
<if test="request.lineId != null">
|
||||
AND a.line_id = #{request.lineId}
|
||||
</if>
|
||||
<if test="request.keyword != null and request.keyword != ''">
|
||||
AND (b.mobile LIKE CONCAT('%', #{request.keyword}, '%') OR b.username LIKE CONCAT('%', #{request.keyword}, '%'))
|
||||
</if>
|
||||
<if test="request.visitNo != null and request.visitNo != ''">
|
||||
AND a.visit_no LIKE CONCAT('%', #{request.visitNo}, '%')
|
||||
</if>
|
||||
<if test="request.visitStartDate != null">
|
||||
AND a.visit_date >= #{request.visitStartDate}
|
||||
</if>
|
||||
<if test="request.visitEndDate != null">
|
||||
AND a.visit_date <= #{request.visitEndDate}
|
||||
</if>
|
||||
<if test="request.status != null">
|
||||
AND a.status = #{request.status}
|
||||
</if>
|
||||
<if test="request.userId != null">
|
||||
AND a.user_id = #{request.userId}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.cool.store.entity.oplog;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
import javax.persistence.*;
|
||||
|
||||
@Table(name = "sys_log_${enterpriseId}")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class SysLogDO {
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 菜单
|
||||
*/
|
||||
private String menus;
|
||||
|
||||
/**
|
||||
* 模块,取最后一级菜单
|
||||
*/
|
||||
private String module;
|
||||
|
||||
/**
|
||||
* 功能
|
||||
*/
|
||||
private String func;
|
||||
|
||||
/**
|
||||
* 子功能
|
||||
*/
|
||||
@Column(name = "sub_func")
|
||||
private String subFunc;
|
||||
|
||||
/**
|
||||
* 操作人id
|
||||
*/
|
||||
@Column(name = "op_user_id")
|
||||
private String opUserId;
|
||||
|
||||
/**
|
||||
* 操作人名称
|
||||
*/
|
||||
@Column(name = "op_user_name")
|
||||
private String opUserName;
|
||||
|
||||
/**
|
||||
* 操作人手机号
|
||||
*/
|
||||
@Column(name = "op_user_mobile")
|
||||
private String opUserMobile;
|
||||
|
||||
/**
|
||||
* 操作时间
|
||||
*/
|
||||
@Column(name = "op_time")
|
||||
private Date opTime;
|
||||
|
||||
/**
|
||||
* 操作类型
|
||||
*/
|
||||
@Column(name = "op_type")
|
||||
private String opType;
|
||||
|
||||
/**
|
||||
* 操作内容
|
||||
*/
|
||||
@Column(name = "op_content")
|
||||
private String opContent;
|
||||
|
||||
/**
|
||||
* 登录ip
|
||||
*/
|
||||
@Column(name = "op_ip")
|
||||
private String opIp;
|
||||
|
||||
/**
|
||||
* 设备信息
|
||||
*/
|
||||
@Column(name = "device_info")
|
||||
private String deviceInfo;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@Column(name = "req_params")
|
||||
private String reqParams;
|
||||
|
||||
/**
|
||||
* 响应参数
|
||||
*/
|
||||
@Column(name = "resp_params")
|
||||
private String respParams;
|
||||
|
||||
/**
|
||||
* 请求路径
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 扩展字段
|
||||
*/
|
||||
@Column(name = "extend_info")
|
||||
private String extendInfo;
|
||||
|
||||
/**
|
||||
* 操作人工号
|
||||
*/
|
||||
@Column(name = "op_user_jobnumber")
|
||||
private String opUserJobnumber;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.cool.store.entity.visit;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
import javax.persistence.*;
|
||||
|
||||
/**
|
||||
* 拜访记录
|
||||
*/
|
||||
@Data
|
||||
@Table(name = "zxjp_visit_record")
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class VisitRecordDO {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 拜访编号
|
||||
*/
|
||||
@Column(name = "visit_no")
|
||||
private String visitNo;
|
||||
|
||||
/**
|
||||
* 线索id
|
||||
*/
|
||||
@Column(name = "line_id")
|
||||
private Long lineId;
|
||||
|
||||
/**
|
||||
* 拜访状态,0待签到 1待签退 2已完成 3已失效
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 是否已完成拜访信息编辑 0否 1是
|
||||
*/
|
||||
@Column(name = "complete_edit")
|
||||
private Integer completeEdit;
|
||||
|
||||
/**
|
||||
* 签到时间
|
||||
*/
|
||||
@Column(name = "sign_in_time")
|
||||
private Date signInTime;
|
||||
|
||||
/**
|
||||
* 签到经纬度
|
||||
*/
|
||||
@Column(name = "sign_in_lon_lat")
|
||||
private String signInLonLat;
|
||||
|
||||
/**
|
||||
* 签到地址
|
||||
*/
|
||||
@Column(name = "sign_in_address")
|
||||
private String signInAddress;
|
||||
|
||||
/**
|
||||
* 签退时间
|
||||
*/
|
||||
@Column(name = "sign_out_time")
|
||||
private Date signOutTime;
|
||||
|
||||
/**
|
||||
* 签退经纬度
|
||||
*/
|
||||
@Column(name = "sign_out_lon_lat")
|
||||
private String signOutLonLat;
|
||||
|
||||
/**
|
||||
* 签退地址
|
||||
*/
|
||||
@Column(name = "sign_out_address")
|
||||
private String signOutAddress;
|
||||
|
||||
/**
|
||||
* 拜访日期
|
||||
*/
|
||||
@Column(name = "visit_date")
|
||||
private Date visitDate;
|
||||
|
||||
/**
|
||||
* 开新店意愿
|
||||
*/
|
||||
private String desire;
|
||||
|
||||
/**
|
||||
* 意向开店城市
|
||||
*/
|
||||
@Column(name = "desire_city")
|
||||
private String desireCity;
|
||||
|
||||
/**
|
||||
* 具体区域
|
||||
*/
|
||||
@Column(name = "desire_district")
|
||||
private String desireDistrict;
|
||||
|
||||
/**
|
||||
* 是否对应现有铺位
|
||||
*/
|
||||
@Column(name = "existing_shop_point")
|
||||
private Integer existingShopPoint;
|
||||
|
||||
/**
|
||||
* 拜访备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Column(name = "update_time")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 加盟商合影图片列表
|
||||
*/
|
||||
private String photos;
|
||||
|
||||
/**
|
||||
* 拜访用户id
|
||||
*/
|
||||
@Column(name = "user_id")
|
||||
private String userId;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.cool.store.request.visit;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录取消Request
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/9
|
||||
*/
|
||||
@Data
|
||||
public class VisitCancelRequest {
|
||||
@ApiModelProperty("拜访记录id")
|
||||
private Long id;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.cool.store.request.visit;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录编辑Request
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/8
|
||||
*/
|
||||
@Data
|
||||
public class VisitEditRequest {
|
||||
@ApiModelProperty("拜访记录id")
|
||||
@NotNull(message = "拜访记录id不能为空")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("拜访日期")
|
||||
@NotNull(message = "拜访日期不能为空")
|
||||
private Date visitDate;
|
||||
|
||||
@ApiModelProperty("开新店意愿,字典表visit_desire")
|
||||
@NotBlank(message = "开新店意愿不能为空")
|
||||
private String desire;
|
||||
|
||||
@ApiModelProperty("意向开店城市")
|
||||
private String desireCity;
|
||||
|
||||
@ApiModelProperty("具体区域")
|
||||
private String desireDistrict;
|
||||
|
||||
@ApiModelProperty("是否对应现有铺位")
|
||||
private Integer existingShopPoint;
|
||||
|
||||
@ApiModelProperty("拜访备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty("加盟商合影图片列表")
|
||||
private String photos;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.cool.store.request.visit;
|
||||
|
||||
import com.cool.store.common.PageBasicInfo;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访加盟商查询Request
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/9
|
||||
*/
|
||||
@Data
|
||||
public class VisitPartnerQueryRequest extends PageBasicInfo {
|
||||
@ApiModelProperty("加盟商姓名或手机号")
|
||||
private String keyword;
|
||||
|
||||
@ApiModelProperty(value = "拜访用户id,查询我的拜访时传当前用户", hidden = true)
|
||||
private String userId;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.cool.store.request.visit;
|
||||
|
||||
import com.cool.store.common.PageBasicInfo;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录查询Request
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/9
|
||||
*/
|
||||
@Data
|
||||
public class VisitRecordQueryRequest extends PageBasicInfo {
|
||||
@ApiModelProperty("线索id")
|
||||
private Long lineId;
|
||||
|
||||
@ApiModelProperty("加盟商姓名或手机号")
|
||||
private String keyword;
|
||||
|
||||
@ApiModelProperty("拜访编号")
|
||||
private String visitNo;
|
||||
|
||||
@ApiModelProperty("拜访人")
|
||||
private String visitUserId;
|
||||
|
||||
@ApiModelProperty("拜访开始日期")
|
||||
private Date visitStartDate;
|
||||
|
||||
@ApiModelProperty("拜访结束日期")
|
||||
private Date visitEndDate;
|
||||
|
||||
@ApiModelProperty("拜访状态,0待签到 1待签退 2已完成 3已失效")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "拜访人id", hidden = true)
|
||||
private String userId;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.cool.store.request.visit;
|
||||
|
||||
import com.cool.store.common.PageBasicInfo;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录查询Request
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/9
|
||||
*/
|
||||
@Data
|
||||
public class VisitRecordSimpleQueryRequest extends PageBasicInfo {
|
||||
@ApiModelProperty("线索id")
|
||||
@NotNull(message = "线索id不能为空")
|
||||
private Long lineId;
|
||||
|
||||
@ApiModelProperty("拜访开始日期")
|
||||
private Date visitStartDate;
|
||||
|
||||
@ApiModelProperty("拜访结束日期")
|
||||
private Date visitEndDate;
|
||||
|
||||
@ApiModelProperty(value = "拜访用户id,查询我的拜访时传当前用户", hidden = true)
|
||||
private String userId;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.cool.store.request.visit;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录签到Request
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/8
|
||||
*/
|
||||
@Data
|
||||
public class VisitSignInRequest {
|
||||
@ApiModelProperty("线索id")
|
||||
@NotNull(message = "线索id不能为空")
|
||||
private Long lineId;
|
||||
|
||||
@ApiModelProperty("签到经纬度,经度,维度")
|
||||
@NotBlank(message = "签到经纬度不能为空")
|
||||
private String signInLonLat;
|
||||
|
||||
@ApiModelProperty("签到地址")
|
||||
@NotBlank(message = "签到地址不能为空")
|
||||
private String signInAddress;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.cool.store.request.visit;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录签到Request
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/8
|
||||
*/
|
||||
@Data
|
||||
public class VisitSignOutRequest {
|
||||
@ApiModelProperty("拜访记录id")
|
||||
@NotNull(message = "拜访记录id不能为空")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("签到经纬度,经度,维度")
|
||||
@NotBlank(message = "签到经纬度不能为空")
|
||||
private String signOutLonLat;
|
||||
|
||||
@ApiModelProperty("签到地址")
|
||||
@NotBlank(message = "签到地址不能为空")
|
||||
private String signOutAddress;
|
||||
}
|
||||
@@ -236,4 +236,6 @@ public class LineInfoVO {
|
||||
|
||||
private String franchiseBrand;
|
||||
|
||||
@ApiModelProperty("被拜访次数")
|
||||
private Integer visitNum;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.cool.store.vo.tp;
|
||||
|
||||
import com.cool.store.annotation.DictField;
|
||||
import com.cool.store.enums.tp.TpFormStatusEnum;
|
||||
import com.cool.store.enums.tp.TpFormTypeEnum;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
@@ -73,6 +74,13 @@ public class TpPenaltyApplyDetailVO {
|
||||
@ApiModelProperty("状态")
|
||||
private String status;
|
||||
|
||||
@ApiModelProperty("状态名称")
|
||||
private String statusName;
|
||||
|
||||
public String getStatusName() {
|
||||
return TpFormStatusEnum.getMsgByStatus(this.status);
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return TpFormTypeEnum.getMsgByType(this.type);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.cool.store.vo.tp;
|
||||
|
||||
import com.cool.store.annotation.DictField;
|
||||
import com.cool.store.enums.tp.TpFormStatusEnum;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -61,4 +62,11 @@ public class TpRewardApplyDetailVO {
|
||||
|
||||
@ApiModelProperty("状态")
|
||||
private String status;
|
||||
|
||||
@ApiModelProperty("状态名称")
|
||||
private String statusName;
|
||||
|
||||
public String getStatusName() {
|
||||
return TpFormStatusEnum.getMsgByStatus(this.status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.cool.store.vo.visit;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访加盟商列表VO
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/9
|
||||
*/
|
||||
@Data
|
||||
public class VisitPartnerListVO {
|
||||
@ApiModelProperty("线索id")
|
||||
private Long lineId;
|
||||
|
||||
@ApiModelProperty("加盟商姓名")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("加盟商手机号")
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty("开店数量")
|
||||
private Integer openNum;
|
||||
|
||||
@ApiModelProperty("被拜访次数")
|
||||
private Integer visitNum;
|
||||
|
||||
@ApiModelProperty("我的拜访次数")
|
||||
private Integer myVisitNum;
|
||||
|
||||
@ApiModelProperty("新老加盟商,0新 1老")
|
||||
private Integer isVeteran;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.cool.store.vo.visit;
|
||||
|
||||
import com.cool.store.annotation.DictField;
|
||||
import com.cool.store.enums.visit.VisitStatusEnum;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录详情VO
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/9
|
||||
*/
|
||||
@Data
|
||||
public class VisitRecordDetailVO {
|
||||
@ApiModelProperty("id")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("加盟商姓名")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("加盟商手机号")
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty("开店数量")
|
||||
private Integer openNum;
|
||||
|
||||
@ApiModelProperty("被拜访次数")
|
||||
private Integer visitNum;
|
||||
|
||||
@ApiModelProperty("拜访编号")
|
||||
private String visitNo;
|
||||
|
||||
@ApiModelProperty("拜访日期")
|
||||
private Date visitDate;
|
||||
|
||||
@ApiModelProperty("签到地址")
|
||||
private String signInAddress;
|
||||
|
||||
@ApiModelProperty("签到时间")
|
||||
private Date signInTime;
|
||||
|
||||
@ApiModelProperty("签退地址")
|
||||
private String signOutAddress;
|
||||
|
||||
@ApiModelProperty("签退时间")
|
||||
private Date signOutTime;
|
||||
|
||||
@ApiModelProperty("开新店意愿")
|
||||
private String desire;
|
||||
|
||||
@ApiModelProperty("开新店意愿名称")
|
||||
@DictField
|
||||
private String desireName;
|
||||
|
||||
@ApiModelProperty("意向开店城市")
|
||||
private String desireCity;
|
||||
|
||||
@ApiModelProperty("意向开店城市名称")
|
||||
private String desireCityName;
|
||||
|
||||
@ApiModelProperty("具体区域")
|
||||
private String desireDistrict;
|
||||
|
||||
@ApiModelProperty("具体区域名称")
|
||||
private String desireDistrictName;
|
||||
|
||||
@ApiModelProperty("是否对应现有铺位")
|
||||
private Integer existingShopPoint;
|
||||
|
||||
@ApiModelProperty("拜访备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty("加盟商合影图片列表")
|
||||
private String photos;
|
||||
|
||||
@ApiModelProperty("拜访状态")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("拜访状态名称")
|
||||
private String statusName;
|
||||
|
||||
@ApiModelProperty("是否老加盟商")
|
||||
private Integer isVeteran;
|
||||
|
||||
@ApiModelProperty("拜访人ID")
|
||||
private String userId;
|
||||
|
||||
@ApiModelProperty("拜访人名称")
|
||||
private String userName;
|
||||
|
||||
public String getStatusName() {
|
||||
return VisitStatusEnum.getDescByStatus(status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.cool.store.vo.visit;
|
||||
|
||||
import com.cool.store.enums.visit.VisitStatusEnum;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录列表VO
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/9
|
||||
*/
|
||||
@Data
|
||||
public class VisitRecordListVO {
|
||||
@ApiModelProperty("id")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "线索id", hidden = true)
|
||||
private Long lineId;
|
||||
|
||||
@ApiModelProperty("加盟商姓名")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("加盟商手机号")
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty("拜访编号")
|
||||
private String visitNo;
|
||||
|
||||
@ApiModelProperty("拜访日期")
|
||||
private Date visitDate;
|
||||
|
||||
@ApiModelProperty("签到地址")
|
||||
private String signInAddress;
|
||||
|
||||
@ApiModelProperty("开新店意愿")
|
||||
private String desire;
|
||||
|
||||
@ApiModelProperty("意向开店城市")
|
||||
private String desireCity;
|
||||
|
||||
@ApiModelProperty("意向开店城市名称")
|
||||
private String desireCityName;
|
||||
|
||||
@ApiModelProperty("具体区域")
|
||||
private String desireDistrict;
|
||||
|
||||
@ApiModelProperty("具体区域名称")
|
||||
private String desireDistrictName;
|
||||
|
||||
@ApiModelProperty("是否对应现有铺位")
|
||||
private Integer existingShopPoint;
|
||||
|
||||
@ApiModelProperty("加盟商合影图片列表")
|
||||
private String photos;
|
||||
|
||||
@ApiModelProperty("拜访状态")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("拜访状态名称")
|
||||
private String statusName;
|
||||
|
||||
@ApiModelProperty("新老加盟商,0新 1老")
|
||||
private Integer isVeteran;
|
||||
|
||||
@ApiModelProperty("拜访人userId")
|
||||
private String visitUserId;
|
||||
|
||||
@ApiModelProperty("拜访人")
|
||||
private String visitUserName;
|
||||
|
||||
public String getStatusName() {
|
||||
return VisitStatusEnum.getDescByStatus(status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.cool.store.vo.visit;
|
||||
|
||||
import com.cool.store.enums.visit.VisitStatusEnum;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录简单信息列表VO
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/9
|
||||
*/
|
||||
@Data
|
||||
public class VisitRecordSimpleListVO {
|
||||
@ApiModelProperty("拜访记录id")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(hidden = true)
|
||||
private Long lineId;
|
||||
|
||||
@ApiModelProperty("加盟商姓名")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("加盟商手机号")
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty("拜访编号")
|
||||
private String visitNo;
|
||||
|
||||
@ApiModelProperty("拜访日期")
|
||||
private Date visitDate;
|
||||
|
||||
@ApiModelProperty("拜访状态,0待签到 1待签退 2已完成 3已失效")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("拜访状态名称")
|
||||
private String statusName;
|
||||
|
||||
@ApiModelProperty("拜访人ID")
|
||||
private String userId;
|
||||
|
||||
@ApiModelProperty("拜访人名称")
|
||||
private String userName;
|
||||
|
||||
public String getStatusName() {
|
||||
return VisitStatusEnum.getDescByStatus(status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.cool.store.vo.visit;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录状态统计
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2026/1/27
|
||||
*/
|
||||
@Data
|
||||
public class VisitRecordStatusStatisticsVO {
|
||||
@ApiModelProperty("本月已完成数量")
|
||||
private Integer monthCompletedCount;
|
||||
|
||||
@ApiModelProperty("已完成数量")
|
||||
private Integer completedCount;
|
||||
|
||||
@ApiModelProperty("未完成数量")
|
||||
private Integer uncompletedCount;
|
||||
|
||||
@ApiModelProperty("已失效数量")
|
||||
private Integer invalidCount;
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import com.cool.store.enums.RocketMqGroupEnum;
|
||||
import com.cool.store.mq.RocketMqConfig;
|
||||
import com.cool.store.mq.consumer.listener.ShopDecorationAssignListener;
|
||||
import com.cool.store.mq.consumer.listener.StoreUserUpdateListener;
|
||||
import com.cool.store.mq.consumer.listener.VisitRecordListener;
|
||||
import com.cool.store.mq.consumer.listener.XfsgTrainingPersonSyncListener;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -38,6 +39,8 @@ public class ConsumerClient {
|
||||
private StoreUserUpdateListener storeUserUpdateListener;
|
||||
@Resource
|
||||
private ShopDecorationAssignListener shopDecorationAssignListener;
|
||||
@Resource
|
||||
private VisitRecordListener visitRecordListener;
|
||||
|
||||
/**
|
||||
* 获取通用配置
|
||||
@@ -117,4 +120,17 @@ public class ConsumerClient {
|
||||
return consumerBean;
|
||||
}
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "shutdown")
|
||||
public ConsumerBean visitRecordInvalid() {
|
||||
RocketMqGroupEnum groupEnum = RocketMqGroupEnum.VISIT_RECORD_INVALID;
|
||||
ConsumerBean consumerBean = new ConsumerBean();
|
||||
//配置文件
|
||||
Properties properties = getCommonProperties(groupEnum);
|
||||
consumerBean.setProperties(properties);
|
||||
Map<Subscription, MessageListener> commonSubscriptionTable = getCommonSubscriptionTable(groupEnum, visitRecordListener);
|
||||
//订阅多个topic如上面设置
|
||||
consumerBean.setSubscriptionTable(commonSubscriptionTable);
|
||||
return consumerBean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.cool.store.mq.consumer.listener;
|
||||
|
||||
import com.aliyun.openservices.ons.api.Action;
|
||||
import com.aliyun.openservices.ons.api.ConsumeContext;
|
||||
import com.aliyun.openservices.ons.api.Message;
|
||||
import com.aliyun.openservices.ons.api.MessageListener;
|
||||
import com.cool.store.constants.CommonConstants;
|
||||
import com.cool.store.service.visit.VisitRecordService;
|
||||
import com.cool.store.utils.RedisUtilPool;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录失效listener
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2026/1/26
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class VisitRecordListener implements MessageListener {
|
||||
private final RedisUtilPool redisUtilPool;
|
||||
private final VisitRecordService visitRecordService;
|
||||
|
||||
|
||||
@Override
|
||||
public Action consume(Message message, ConsumeContext consumeContext) {
|
||||
String text = new String(message.getBody());
|
||||
if (StringUtils.isBlank(text)) {
|
||||
log.info("消息体为空,tag:{},messageId:{}", message.getTag(), message.getMsgID());
|
||||
return Action.CommitMessage;
|
||||
}
|
||||
String lockKey = "VisitRecordListener:" + message.getMsgID();
|
||||
boolean lock = redisUtilPool.setNxExpire(lockKey, message.getMsgID(), CommonConstants.NORMAL_LOCK_TIMES);
|
||||
if (lock) {
|
||||
try {
|
||||
visitRecordService.recordInvalid(Long.valueOf(text));
|
||||
} catch (Exception e) {
|
||||
log.error("VisitRecordListener consume error", e);
|
||||
return Action.ReconsumeLater;
|
||||
} finally {
|
||||
redisUtilPool.delKey(lockKey);
|
||||
}
|
||||
log.info("消费成功,tag:{},messageId:{},reqBody={}", message.getTag(), message.getMsgID(), text);
|
||||
return Action.CommitMessage;
|
||||
}
|
||||
return Action.ReconsumeLater;
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,8 @@ public interface UserAuthMappingService {
|
||||
*/
|
||||
List<String> getAuthRegionIdAndSubRegionIdByUserId(String userId);
|
||||
|
||||
List<String> getAuthRegionIdAndSubRegionIdExcludeStoreByUserId(String userId);
|
||||
|
||||
/**
|
||||
* 获取所有管辖下的区域ID 不包含门店
|
||||
* @param userId
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.cool.store.constants.CommonConstants;
|
||||
import com.cool.store.constants.RedisConstant;
|
||||
import com.cool.store.context.LoginUserInfo;
|
||||
import com.cool.store.dao.*;
|
||||
import com.cool.store.dao.visit.VisitRecordDAO;
|
||||
import com.cool.store.entity.*;
|
||||
import com.cool.store.enums.*;
|
||||
import com.cool.store.enums.point.PayBusinessTypeEnum;
|
||||
@@ -91,6 +92,8 @@ public class LineServiceImpl implements LineService {
|
||||
QualificationsInfoDAO qualificationsInfoDAO;
|
||||
@Resource
|
||||
EnterpriseService enterpriseService;
|
||||
@Resource
|
||||
VisitRecordDAO visitRecordDAO;
|
||||
|
||||
|
||||
@Override
|
||||
@@ -186,6 +189,7 @@ public class LineServiceImpl implements LineService {
|
||||
}
|
||||
}
|
||||
result.setDevelopmentManager(developmentManagerName.toString());
|
||||
result.setVisitNum(visitRecordDAO.getCompleteVisitNum(result.getId()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +119,20 @@ public class UserAuthMappingServiceImpl implements UserAuthMappingService {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> getAuthRegionIdAndSubRegionIdExcludeStoreByUserId(String userId) {
|
||||
List<UserAuthMappingDO> userAuthMapping = listUserAuthMappingByUserId(userId);
|
||||
if (CollectionUtils.isEmpty(userAuthMapping)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
List<String> regionIds = userAuthMapping.stream().map(UserAuthMappingDO::getMappingId).collect(Collectors.toList());
|
||||
List<String> subRegionIds = regionMapper.getSubRegionIdsExcludeStore(regionIds);
|
||||
if (CollectionUtils.isNotEmpty(subRegionIds)) {
|
||||
regionIds.addAll(subRegionIds);
|
||||
}
|
||||
return regionIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAuthStoreIdAndSubRegionIdByUserId(String userId) {
|
||||
List<UserAuthMappingDO> userAuthMapping = listUserAuthMappingByUserId(userId);
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.cool.store.service.visit;
|
||||
|
||||
import com.cool.store.request.visit.*;
|
||||
import com.cool.store.vo.visit.*;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录Service
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/8
|
||||
*/
|
||||
public interface VisitRecordService {
|
||||
|
||||
/**
|
||||
* 签到
|
||||
* @param request 拜访记录签到Request
|
||||
* @return 拜访记录id
|
||||
*/
|
||||
String signIn(VisitSignInRequest request);
|
||||
|
||||
/**
|
||||
* 签退
|
||||
* @param request 拜访记录签到Request
|
||||
* @return 拜访记录id
|
||||
*/
|
||||
String signOut(VisitSignOutRequest request);
|
||||
|
||||
/**
|
||||
* 编辑拜访记录
|
||||
* @param request 拜访记录编辑Request
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean editRecord(VisitEditRequest request);
|
||||
|
||||
/**
|
||||
* 拜访加盟商列表
|
||||
* @param request 拜访加盟商查询Request
|
||||
* @return 拜访加盟商列表VO
|
||||
*/
|
||||
PageInfo<VisitPartnerListVO> visitPartnerList(VisitPartnerQueryRequest request);
|
||||
|
||||
/**
|
||||
* 查询拜访记录简单信息
|
||||
* @param request 拜访记录查询Request
|
||||
* @return 拜访记录列表VO
|
||||
*/
|
||||
PageInfo<VisitRecordSimpleListVO> recordSimpleList(VisitRecordSimpleQueryRequest request);
|
||||
|
||||
/**
|
||||
* 获取拜访记录详情
|
||||
* @param id 拜访记录id
|
||||
* @return 拜访记录详情VO
|
||||
*/
|
||||
VisitRecordDetailVO getDetail(Long id);
|
||||
|
||||
/**
|
||||
* 取消拜访
|
||||
* @param request 拜访记录取消Request
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean cancelVisit(VisitCancelRequest request);
|
||||
|
||||
/**
|
||||
* 获取拜访记录列表
|
||||
* @param request 拜访记录查询Request
|
||||
* @return 拜访记录列表VO
|
||||
*/
|
||||
PageInfo<VisitRecordListVO> recordList(VisitRecordQueryRequest request);
|
||||
|
||||
/**
|
||||
* 记录失效
|
||||
* @param id id
|
||||
*/
|
||||
void recordInvalid(Long id);
|
||||
|
||||
/**
|
||||
* 拜访记录状态统计
|
||||
* @return 拜访记录状态统计VO
|
||||
*/
|
||||
VisitRecordStatusStatisticsVO countStatusStatistics(VisitRecordQueryRequest request);
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
package com.cool.store.service.visit.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollStreamUtil;
|
||||
import com.cool.store.constants.CommonConstants;
|
||||
import com.cool.store.context.CurrentUserHolder;
|
||||
import com.cool.store.dao.*;
|
||||
import com.cool.store.dao.ad.AdDistrictDAO;
|
||||
import com.cool.store.dao.store.StoreMasterSignerInfoDAO;
|
||||
import com.cool.store.dao.visit.VisitRecordDAO;
|
||||
import com.cool.store.dto.region.BigRegionDTO;
|
||||
import com.cool.store.entity.LineInfoDO;
|
||||
import com.cool.store.entity.QualificationsInfoDO;
|
||||
import com.cool.store.entity.StoreDO;
|
||||
import com.cool.store.entity.store.StoreMasterSignerInfoDO;
|
||||
import com.cool.store.entity.visit.VisitRecordDO;
|
||||
import com.cool.store.enums.ErrorCodeEnum;
|
||||
import com.cool.store.enums.RocketMqTagEnum;
|
||||
import com.cool.store.enums.visit.VisitStatusEnum;
|
||||
import com.cool.store.exception.ServiceException;
|
||||
import com.cool.store.mq.producer.SimpleMessageService;
|
||||
import com.cool.store.request.visit.*;
|
||||
import com.cool.store.service.SysRoleService;
|
||||
import com.cool.store.service.UserAuthMappingService;
|
||||
import com.cool.store.service.dict.impl.DictService;
|
||||
import com.cool.store.service.visit.VisitRecordService;
|
||||
import com.cool.store.utils.BeanUtil;
|
||||
import com.cool.store.utils.poi.StringUtils;
|
||||
import com.cool.store.vo.visit.*;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/8
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class VisitRecordServiceImpl implements VisitRecordService {
|
||||
private final VisitRecordDAO visitRecordDAO;
|
||||
private final UserAuthMappingService userAuthMappingService;
|
||||
private final QualificationsInfoDAO qualificationsInfoDAO;
|
||||
private final StoreDao storeDao;
|
||||
private final StoreMasterSignerInfoDAO storeSignerDAO;
|
||||
private final LineInfoDAO lineInfoDAO;
|
||||
private final BigRegionDAO bigRegionDAO;
|
||||
private final DictService dictService;
|
||||
private final SysRoleService sysRoleService;
|
||||
private final SimpleMessageService simpleMessageService;
|
||||
private final AdDistrictDAO adDistrictDAO;
|
||||
private final EnterpriseUserDAO enterpriseUserDAO;
|
||||
|
||||
@Override
|
||||
public String signIn(VisitSignInRequest request) {
|
||||
VisitRecordDO record = VisitRecordDO.builder()
|
||||
.visitNo(generateVisitNo())
|
||||
.lineId(request.getLineId())
|
||||
.signInLonLat(request.getSignInLonLat())
|
||||
.signInAddress(request.getSignInAddress())
|
||||
.status(VisitStatusEnum.N_SIGN_OUT.getStatus())
|
||||
.signInTime(new Date())
|
||||
.userId(CurrentUserHolder.getUserId())
|
||||
.build();
|
||||
visitRecordDAO.insertSelective(record);
|
||||
simpleMessageService.send(String.valueOf(record.getId()), RocketMqTagEnum.VISIT_RECORD_INVALID, System.currentTimeMillis() + 12 * 60 * 60 * 1000);
|
||||
return record.getId().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String signOut(VisitSignOutRequest request) {
|
||||
VisitRecordDO old = visitRecordDAO.getById(request.getId());
|
||||
verify(old);
|
||||
if (CommonConstants.INDEX_ZERO.equals(old.getCompleteEdit())) {
|
||||
throw new ServiceException(ErrorCodeEnum.VISIT_RECORD_NOT_COMPLETE_EDIT);
|
||||
}
|
||||
VisitRecordDO record = VisitRecordDO.builder()
|
||||
.id(request.getId())
|
||||
.signOutTime(new Date())
|
||||
.signOutLonLat(request.getSignOutLonLat())
|
||||
.signOutAddress(request.getSignOutAddress())
|
||||
.status(VisitStatusEnum.COMPLETE.getStatus())
|
||||
.build();
|
||||
visitRecordDAO.updateSelective(record);
|
||||
return record.getId().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean editRecord(VisitEditRequest request) {
|
||||
VisitRecordDO old = visitRecordDAO.getById(request.getId());
|
||||
verify(old);
|
||||
VisitRecordDO record = BeanUtil.toBean(request, VisitRecordDO.class);
|
||||
record.setCompleteEdit(CommonConstants.INDEX_ONE);
|
||||
return visitRecordDAO.updateSelective(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<VisitPartnerListVO> visitPartnerList(VisitPartnerQueryRequest request) {
|
||||
List<Long> authRegionIds = null;
|
||||
String currentUserId = CurrentUserHolder.getUserId();
|
||||
if (!sysRoleService.checkIsAdmin(currentUserId)) {
|
||||
authRegionIds = userAuthMappingService.getAuthRegionIdAndSubRegionIdExcludeStoreByUserId(currentUserId)
|
||||
.stream()
|
||||
.map(Long::valueOf)
|
||||
.collect(Collectors.toList());
|
||||
List<BigRegionDTO> bigRegionList = bigRegionDAO.queryAllBigRegion(null, null, null);
|
||||
Set<Long> bigRegionIds = CollStreamUtil.toSet(bigRegionList, BigRegionDTO::getRegionId);
|
||||
authRegionIds.retainAll(bigRegionIds);
|
||||
if (CollectionUtils.isEmpty(authRegionIds)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
}
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<Long> lineIds = visitRecordDAO.getPartnerLineId(authRegionIds, request.getKeyword(), request.getUserId());
|
||||
PageInfo<Long> page = new PageInfo<>(lineIds);
|
||||
List<VisitPartnerListVO> list = visitRecordDAO.getVisitRecordListByLineIds(lineIds, request.getUserId());
|
||||
PageInfo<VisitPartnerListVO> result = BeanUtil.toPage(page, VisitPartnerListVO.class);
|
||||
result.setList(list);
|
||||
|
||||
List<LineInfoDO> lineList = lineInfoDAO.getByLineIds(lineIds);
|
||||
Map<Long, LineInfoDO> lineMap = CollStreamUtil.toMap(lineList, LineInfoDO::getId, v -> v);
|
||||
Map<Long, Integer> storeNumMap = getStoreNumMap(lineIds);
|
||||
list.forEach(v -> {
|
||||
v.setOpenNum(storeNumMap.getOrDefault(v.getLineId(), 0));
|
||||
v.setIsVeteran(v.getOpenNum() > 0 ? 1 : 0);
|
||||
LineInfoDO lineInfoDO = lineMap.get(v.getLineId());
|
||||
if (Objects.nonNull(lineInfoDO)) {
|
||||
v.setName(lineInfoDO.getUsername());
|
||||
v.setMobile(lineInfoDO.getMobile());
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<Long, Integer> getStoreNumMap(List<Long> lineIds) {
|
||||
List<QualificationsInfoDO> qualificationList = qualificationsInfoDAO.getByLineIds(lineIds);
|
||||
Map<Long, String> idCardMap = CollStreamUtil.toMap(qualificationList, QualificationsInfoDO::getLineId, QualificationsInfoDO::getIdCardNo);
|
||||
// 根据身份证查询对应签约人开店数量
|
||||
List<StoreMasterSignerInfoDO> storeSignerList = storeSignerDAO.getListByIdCard(idCardMap.values());
|
||||
List<String> storeIds = CollStreamUtil.toList(storeSignerList, StoreMasterSignerInfoDO::getStoreId);
|
||||
List<StoreDO> effectiveStoreList = storeDao.getEffectiveStoreByStoreIds(storeIds);
|
||||
Set<String> effectiveStoreIds = CollStreamUtil.toSet(effectiveStoreList, StoreDO::getStoreId);
|
||||
|
||||
Map<String, Integer> storeNumMap = new HashMap<>();
|
||||
for (StoreMasterSignerInfoDO signerInfoDO : storeSignerList) {
|
||||
if (effectiveStoreIds.contains(signerInfoDO.getStoreId())) {
|
||||
storeNumMap.compute(signerInfoDO.getSigner1IdCardNo(), (k, v) -> Objects.isNull(v) ? 1 : v + 1);
|
||||
storeNumMap.compute(signerInfoDO.getSigner2IdCardNo(), (k, v) -> Objects.isNull(v) ? 1 : v + 1);
|
||||
}
|
||||
}
|
||||
return CollStreamUtil.toMap(lineIds, v -> v, v -> storeNumMap.getOrDefault(idCardMap.get(v), 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<VisitRecordSimpleListVO> recordSimpleList(VisitRecordSimpleQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<VisitRecordDO> list = visitRecordDAO.getByLineId(request.getLineId(), request.getVisitStartDate(), request.getVisitEndDate(), request.getUserId());
|
||||
PageInfo<VisitRecordDO> page = new PageInfo<>(list);
|
||||
Set<Long> lineIds = CollStreamUtil.toSet(list, VisitRecordDO::getLineId);
|
||||
Set<String> userIdList = CollStreamUtil.toSet(list, VisitRecordDO::getUserId);
|
||||
Map<String, String> userNameMap = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(userIdList)){
|
||||
userNameMap = enterpriseUserDAO.getUserNameMap(new ArrayList<>(userIdList));
|
||||
}
|
||||
List<LineInfoDO> lineList = lineInfoDAO.getByLineIds(new ArrayList<>(lineIds));
|
||||
Map<Long, LineInfoDO> lineMap = CollStreamUtil.toMap(lineList, LineInfoDO::getId, v -> v);
|
||||
PageInfo<VisitRecordSimpleListVO> result = BeanUtil.toPage(page, VisitRecordSimpleListVO.class);
|
||||
Map<String, String> finalUserNameMap = userNameMap;
|
||||
result.getList().forEach(v -> {
|
||||
LineInfoDO lineInfoDO = lineMap.get(v.getLineId());
|
||||
String userName = finalUserNameMap.getOrDefault(v.getUserId(), "");
|
||||
v.setUserName(userName);
|
||||
if (Objects.nonNull(lineInfoDO)) {
|
||||
v.setName(lineInfoDO.getUsername());
|
||||
v.setMobile(lineInfoDO.getMobile());
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisitRecordDetailVO getDetail(Long id) {
|
||||
VisitRecordDO record = visitRecordDAO.getById(id);
|
||||
if (Objects.isNull(record)) {
|
||||
throw new ServiceException(ErrorCodeEnum.VISIT_RECORD_NOT_EXIST);
|
||||
}
|
||||
VisitRecordDetailVO vo = BeanUtil.toBean(record, VisitRecordDetailVO.class);
|
||||
LineInfoDO lineInfo = lineInfoDAO.getLineInfo(record.getLineId());
|
||||
if (Objects.nonNull(lineInfo)) {
|
||||
vo.setName(lineInfo.getUsername());
|
||||
vo.setMobile(lineInfo.getMobile());
|
||||
}
|
||||
if (StringUtils.isNotBlank(record.getUserId())){
|
||||
String userName = enterpriseUserDAO.getUserName(record.getUserId());
|
||||
vo.setUserId(record.getUserId());
|
||||
vo.setUserName(userName);
|
||||
}
|
||||
Map<Long, Integer> storeNumMap = getStoreNumMap(Collections.singletonList(record.getLineId()));
|
||||
vo.setOpenNum(storeNumMap.getOrDefault(record.getLineId(), 0));
|
||||
vo.setIsVeteran(storeNumMap.getOrDefault(record.getLineId(), 0) > 0 ? 1 : 0);
|
||||
List<VisitPartnerListVO> list = visitRecordDAO.getVisitRecordListByLineIds(Collections.singletonList(record.getLineId()), null);
|
||||
Map<String, String> adNameMap = adDistrictDAO.getNameByCodes(Arrays.asList(vo.getDesireCity(), vo.getDesireDistrict()));
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
VisitPartnerListVO partner = list.get(0);
|
||||
vo.setVisitNum(partner.getVisitNum());
|
||||
vo.setDesireCityName(adNameMap.get(vo.getDesireCity()));
|
||||
vo.setDesireDistrictName(adNameMap.get(vo.getDesireDistrict()));
|
||||
}
|
||||
dictService.fillDictField(vo);
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean cancelVisit(VisitCancelRequest request) {
|
||||
return visitRecordDAO.deleteById(request.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<VisitRecordListVO> recordList(VisitRecordQueryRequest request) {
|
||||
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||
List<VisitRecordListVO> list = visitRecordDAO.getVisitRecordList(request);
|
||||
PageInfo<VisitRecordListVO> page = new PageInfo<>(list);
|
||||
Set<Long> lineIds = CollStreamUtil.toSet(list, VisitRecordListVO::getLineId);
|
||||
Set<String> userIdList = CollStreamUtil.toSet(list, VisitRecordListVO::getVisitUserId);
|
||||
Map<String, String> userNameMap = new HashMap<>();
|
||||
if (CollectionUtils.isNotEmpty(userIdList)){
|
||||
userNameMap = enterpriseUserDAO.getUserNameMap(new ArrayList<>(userIdList));
|
||||
}
|
||||
List<String> adCodes = list.stream()
|
||||
.flatMap(v -> Stream.of(v.getDesireCity(), v.getDesireDistrict()))
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
Map<String, String> adNameMap = adDistrictDAO.getNameByCodes(adCodes);
|
||||
Map<Long, Integer> storeNumMap = getStoreNumMap(new ArrayList<>(lineIds));
|
||||
Map<String, String> finalUserNameMap = userNameMap;
|
||||
list.forEach(v -> {
|
||||
v.setIsVeteran(storeNumMap.getOrDefault(v.getLineId(), 0) > 0 ? 1 : 0);
|
||||
v.setDesireCityName(adNameMap.get(v.getDesireCity()));
|
||||
v.setDesireDistrictName(adNameMap.get(v.getDesireDistrict()));
|
||||
v.setVisitUserName(finalUserNameMap.get(v.getVisitUserId()));
|
||||
});
|
||||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordInvalid(Long id) {
|
||||
VisitRecordDO record = visitRecordDAO.getById(id);
|
||||
if (Objects.nonNull(record) && VisitStatusEnum.N_SIGN_OUT.getStatus().equals(record.getStatus())) {
|
||||
VisitRecordDO update = VisitRecordDO.builder().id(record.getId()).status(VisitStatusEnum.INVALID.getStatus()).build();
|
||||
visitRecordDAO.updateSelective(update);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VisitRecordStatusStatisticsVO countStatusStatistics(VisitRecordQueryRequest request) {
|
||||
return visitRecordDAO.countStatusStatistics(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验操作权限及拜访状态
|
||||
*/
|
||||
private void verify(VisitRecordDO record) {
|
||||
if (Objects.isNull(record)) {
|
||||
throw new ServiceException(ErrorCodeEnum.VISIT_RECORD_NOT_EXIST);
|
||||
}
|
||||
if (VisitStatusEnum.INVALID.getStatus().equals(record.getStatus())) {
|
||||
throw new ServiceException(ErrorCodeEnum.VISIT_RECORD_INVALID);
|
||||
}
|
||||
if (VisitStatusEnum.COMPLETE.getStatus().equals(record.getStatus())) {
|
||||
throw new ServiceException(ErrorCodeEnum.VISIT_RECORD_COMPLETE);
|
||||
}
|
||||
if (!record.getUserId().equals(CurrentUserHolder.getUserId())) {
|
||||
throw new ServiceException(ErrorCodeEnum.VISIT_RECORD_NOT_YOUR_OWN);
|
||||
}
|
||||
}
|
||||
|
||||
private String generateVisitNo() {
|
||||
return "V" + System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.cool.store.controller.webb;
|
||||
|
||||
import com.cool.store.context.CurrentUserHolder;
|
||||
import com.cool.store.request.visit.*;
|
||||
import com.cool.store.response.ResponseResult;
|
||||
import com.cool.store.service.visit.VisitRecordService;
|
||||
import com.cool.store.vo.visit.*;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 拜访记录 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2025/12/9
|
||||
*/
|
||||
@Api(tags = "拜访记录")
|
||||
@RestController
|
||||
@RequestMapping("/pc/visit/record")
|
||||
@RequiredArgsConstructor
|
||||
public class VisitRecordController {
|
||||
|
||||
private final VisitRecordService visitRecordService;
|
||||
|
||||
@ApiOperation("签到")
|
||||
@PostMapping("/signIn")
|
||||
public ResponseResult<String> signIn(@RequestBody @Validated VisitSignInRequest request) {
|
||||
return ResponseResult.success(visitRecordService.signIn(request));
|
||||
}
|
||||
|
||||
@ApiOperation("签退")
|
||||
@PostMapping("/signOut")
|
||||
public ResponseResult<String> signOut(@RequestBody @Validated VisitSignOutRequest request) {
|
||||
return ResponseResult.success(visitRecordService.signOut(request));
|
||||
}
|
||||
|
||||
@ApiOperation("编辑拜访记录")
|
||||
@PostMapping("/editRecord")
|
||||
public ResponseResult<Boolean> editRecord(@RequestBody @Validated VisitEditRequest request) {
|
||||
return ResponseResult.success(visitRecordService.editRecord(request));
|
||||
}
|
||||
|
||||
@ApiOperation("拜访加盟商列表")
|
||||
@PostMapping("/partnerList")
|
||||
public ResponseResult<PageInfo<VisitPartnerListVO>> visitPartnerList(@RequestBody VisitPartnerQueryRequest request) {
|
||||
return ResponseResult.success(visitRecordService.visitPartnerList(request));
|
||||
}
|
||||
|
||||
@ApiOperation("我的拜访加盟商列表")
|
||||
@PostMapping("/personPartnerList")
|
||||
public ResponseResult<PageInfo<VisitPartnerListVO>> personVisitPartnerList(@RequestBody VisitPartnerQueryRequest request) {
|
||||
request.setUserId(CurrentUserHolder.getUserId());
|
||||
return ResponseResult.success(visitRecordService.visitPartnerList(request));
|
||||
}
|
||||
|
||||
@ApiOperation("查询拜访记录简单信息(h5使用)")
|
||||
@PostMapping("/simpleList")
|
||||
public ResponseResult<PageInfo<VisitRecordSimpleListVO>> recordSimpleList(@RequestBody VisitRecordSimpleQueryRequest request) {
|
||||
request.setUserId(CurrentUserHolder.getUserId());
|
||||
return ResponseResult.success(visitRecordService.recordSimpleList(request));
|
||||
}
|
||||
|
||||
@ApiOperation("我的查询拜访记录简单信息(h5使用)")
|
||||
@PostMapping("/personSimpleList")
|
||||
public ResponseResult<PageInfo<VisitRecordSimpleListVO>> personRecordSimpleList(@RequestBody VisitRecordSimpleQueryRequest request) {
|
||||
request.setUserId(CurrentUserHolder.getUserId());
|
||||
return ResponseResult.success(visitRecordService.recordSimpleList(request));
|
||||
}
|
||||
|
||||
@ApiOperation("获取拜访记录详情")
|
||||
@GetMapping("/detail")
|
||||
@ApiImplicitParam(name = "id", value = "拜访记录id", required = true, dataType = "Long", paramType = "query")
|
||||
public ResponseResult<VisitRecordDetailVO> getDetail(@NotNull(message = "拜访记录id不能为空") Long id) {
|
||||
return ResponseResult.success(visitRecordService.getDetail(id));
|
||||
}
|
||||
|
||||
@ApiOperation("取消拜访")
|
||||
@PostMapping("/cancel")
|
||||
public ResponseResult<Boolean> cancelVisit(@RequestBody @Validated VisitCancelRequest request) {
|
||||
return ResponseResult.success(visitRecordService.cancelVisit(request));
|
||||
}
|
||||
|
||||
@ApiOperation("获取拜访记录列表")
|
||||
@PostMapping("/list")
|
||||
public ResponseResult<PageInfo<VisitRecordListVO>> recordList(@RequestBody VisitRecordQueryRequest request) {
|
||||
return ResponseResult.success(visitRecordService.recordList(request));
|
||||
}
|
||||
|
||||
@ApiOperation("拜访记录状态统计")
|
||||
@PostMapping("/countStatusStatistics")
|
||||
public ResponseResult<VisitRecordStatusStatisticsVO> countStatusStatistics(@RequestBody VisitRecordQueryRequest request) {
|
||||
return ResponseResult.success(visitRecordService.countStatusStatistics(request));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user