沐梦. 1 miesiąc temu
rodzic
commit
f0fcf6df1a

+ 9 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SalesAnnualFinalizationController.java

@@ -64,4 +64,13 @@ public class SalesAnnualFinalizationController extends BaseController {
     public R<Void> remove(@PathVariable Long[] ids) {
         return toAjax(salesAnnualFinalizationService.deleteWithValidByIds(Arrays.asList(ids), true));
     }
+
+    /**
+     * 转移年度入围项目
+     */
+    @PutMapping("/transfer")
+    public R<Void> transfer(@RequestBody SalesAnnualFinalizationBo bo) {
+        return toAjax(salesAnnualFinalizationService.transfer(bo));
+    }
 }
+

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/SalesAnnualFinalization.java

@@ -172,7 +172,7 @@ public class SalesAnnualFinalization extends TenantEntity {
      * 招标类型
      */
     @TableField(value = "BiddingType")
-    private Integer biddingType;
+    private Integer biddingType = 1;
 
     /**
      * 招标代理机构

+ 24 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SalesAnnualFinalizationBo.java

@@ -9,6 +9,8 @@ import org.dromara.customer.domain.SalesAnnualFinalization;
 
 import java.math.BigDecimal;
 import java.util.Date;
+import java.util.List;
+
 
 /**
  * 年度入围项目业务对象 salesannualfinalization
@@ -170,7 +172,7 @@ public class SalesAnnualFinalizationBo extends BaseEntity {
      * 招标类型
      */
     @Schema(description = "招标类型")
-    private Integer biddingType;
+    private Integer biddingType = 1;
 
     /**
      * 招标代理机构
@@ -202,6 +204,19 @@ public class SalesAnnualFinalizationBo extends BaseEntity {
     @Schema(description = "负责人名称")
     private String leaderName;
 
+    /**
+     * 新负责人ID(兼容前端传参)
+     */
+    @Schema(description = "新负责人ID")
+    private Long newLeaderId;
+
+    /**
+     * 是否保留原负责人为团队成员
+     */
+    @Schema(description = "是否保留原负责人为团队成员")
+    private Boolean keepAsMember;
+
+
     /**
      * 文件编号
      */
@@ -292,4 +307,12 @@ public class SalesAnnualFinalizationBo extends BaseEntity {
     @Schema(description = "服务时间")
     private String serviceTime;
 
+    /**
+     * 批量操作ID列表
+     */
+    @Schema(description = "批量操作ID列表")
+    private List<Long> ids;
+
 }
+
+

+ 7 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SalesAnnualFinalizationVo.java

@@ -103,6 +103,13 @@ public class SalesAnnualFinalizationVo {
     @Schema(description = "部门编号")
     private String deptNo;
 
+    /**
+     * 部门名称
+     */
+    @ExcelProperty(value = "部门名称")
+    @Schema(description = "部门名称")
+    private String deptName;
+
     /**
      * 业务员
      */

+ 16 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/SalesAnnualFinalizationMapper.java

@@ -1,9 +1,15 @@
 package org.dromara.customer.mapper;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 import org.dromara.customer.domain.SalesAnnualFinalization;
+import org.dromara.customer.domain.bo.SalesAnnualFinalizationBo;
 import org.dromara.customer.domain.vo.SalesAnnualFinalizationVo;
 
+import java.util.List;
+
 /**
  * 年度入围项目 Mapper 接口
  *
@@ -12,4 +18,14 @@ import org.dromara.customer.domain.vo.SalesAnnualFinalizationVo;
  */
 public interface SalesAnnualFinalizationMapper extends BaseMapperPlus<SalesAnnualFinalization, SalesAnnualFinalizationVo> {
 
+    /**
+     * 自定义分页查询年度入围列表(关联部门)
+     */
+    IPage<SalesAnnualFinalizationVo> selectSalesAnnualFinalizationList(@Param("page") Page<SalesAnnualFinalizationVo> page, @Param("bo") SalesAnnualFinalizationBo bo);
+
+    /**
+     * 自定义列表查询年度入围列表(关联部门)
+     */
+    List<SalesAnnualFinalizationVo> selectSalesAnnualFinalizationList(@Param("bo") SalesAnnualFinalizationBo bo);
+
 }

+ 6 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISalesAnnualFinalizationService.java

@@ -45,4 +45,10 @@ public interface ISalesAnnualFinalizationService {
      * 批量删除年度入围项目
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 转移年度入围项目
+     */
+    Boolean transfer(SalesAnnualFinalizationBo bo);
 }
+

+ 5 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ITeamMemberService.java

@@ -43,4 +43,9 @@ public interface ITeamMemberService {
      * 新增或更新团队成员(根据 objectNo + userNo 判断)
      */
     Boolean insertOrUpdateMember(TeamMemberBo bo);
+
+    /**
+     * 删除特定的团队成员
+     */
+    Boolean removeMember(Integer dataType, String objectNo, Long userNo);
 }

+ 22 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/FollowUpLogServiceImpl.java

@@ -15,6 +15,8 @@ import org.dromara.customer.domain.vo.CustomerInfoVo;
 import org.dromara.customer.domain.vo.FollowUpLogVo;
 import org.dromara.customer.mapper.CustomerInfoMapper;
 import org.dromara.customer.mapper.FollowUpLogMapper;
+import org.dromara.customer.domain.VisitRoutine;
+import org.dromara.customer.mapper.CrmVisitRoutineMapper;
 import org.dromara.customer.service.IFollowUpLogService;
 import org.springframework.stereotype.Service;
 
@@ -33,6 +35,7 @@ public class FollowUpLogServiceImpl implements IFollowUpLogService {
 
     private final FollowUpLogMapper baseMapper;
     private final CustomerInfoMapper customerInfoMapper;
+    private final CrmVisitRoutineMapper visitRoutineMapper;
 
     /**
      * 查询跟进记录
@@ -116,6 +119,25 @@ public class FollowUpLogServiceImpl implements IFollowUpLogService {
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
             bo.setId(add.getId());
+            
+            // 同步到拜访日程表 (callonschedule)
+            VisitRoutine routine = new VisitRoutine();
+            routine.setRelevanceType(add.getDataType());
+            routine.setObjectNo(add.getObjectNo());
+            routine.setCustomerNo(add.getCustomerNo());
+            routine.setCustomerName(add.getCustomerName());
+            routine.setCallPeopleNo(add.getVisitorNo());
+            routine.setCallPeopleName(add.getVisitor());
+            routine.setCallDate(add.getCallDate());
+            routine.setPurposeVisit(add.getCallAim());
+            routine.setScheduleStatus(1); // 已执行
+            routine.setExecuteTime(add.getCallDate());
+            routine.setImportantLevel(1); // 一般
+            
+            // 生成日程编号
+            routine.setScheduleNo("RC" + cn.hutool.core.date.DateUtil.format(new java.util.Date(), "yyyyMMdd") + cn.hutool.core.util.RandomUtil.randomNumbers(4));
+            
+            visitRoutineMapper.insert(routine);
         }
         return flag;
     }

+ 122 - 17
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SalesAnnualFinalizationServiceImpl.java

@@ -1,12 +1,15 @@
 package org.dromara.customer.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.redis.utils.SequenceUtils;
@@ -15,8 +18,15 @@ import org.dromara.customer.domain.bo.SalesAnnualFinalizationBo;
 import org.dromara.customer.domain.vo.SalesAnnualFinalizationVo;
 import org.dromara.customer.mapper.SalesAnnualFinalizationMapper;
 import org.dromara.customer.service.IOperationLogService;
+import org.dromara.customer.domain.bo.TeamMemberBo;
+import org.dromara.customer.service.ITeamMemberService;
 import org.dromara.customer.service.ISalesAnnualFinalizationService;
+import org.dromara.customer.controller.constant.CustomerConstants;
+import org.dromara.system.api.RemoteUserService;
+import org.dromara.system.api.domain.vo.RemoteUserVo;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
 
 import java.time.Duration;
 import java.util.Collection;
@@ -37,14 +47,17 @@ public class SalesAnnualFinalizationServiceImpl implements ISalesAnnualFinalizat
 
     private final SalesAnnualFinalizationMapper baseMapper;
     private final IOperationLogService operationLogService;
+    private final ITeamMemberService teamMemberService;
+
+    @DubboReference
+    private RemoteUserService remoteUserService;
 
     /**
      * 查询年度入围项目列表
      */
     @Override
     public TableDataInfo<SalesAnnualFinalizationVo> queryPageList(SalesAnnualFinalizationBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<SalesAnnualFinalization> lqw = buildQueryWrapper(bo);
-        Page<SalesAnnualFinalizationVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        IPage<SalesAnnualFinalizationVo> result = baseMapper.selectSalesAnnualFinalizationList(pageQuery.build(), bo);
         return TableDataInfo.build(result);
     }
 
@@ -53,8 +66,7 @@ public class SalesAnnualFinalizationServiceImpl implements ISalesAnnualFinalizat
      */
     @Override
     public List<SalesAnnualFinalizationVo> queryList(SalesAnnualFinalizationBo bo) {
-        LambdaQueryWrapper<SalesAnnualFinalization> lqw = buildQueryWrapper(bo);
-        return baseMapper.selectVoList(lqw);
+        return baseMapper.selectSalesAnnualFinalizationList(bo);
     }
 
     private LambdaQueryWrapper<SalesAnnualFinalization> buildQueryWrapper(SalesAnnualFinalizationBo bo) {
@@ -68,6 +80,7 @@ public class SalesAnnualFinalizationServiceImpl implements ISalesAnnualFinalizat
         lqw.eq(bo.getProjectStatus() != null, SalesAnnualFinalization::getProjectStatus, bo.getProjectStatus());
         lqw.eq(bo.getProjectLevel() != null, SalesAnnualFinalization::getProjectLevel, bo.getProjectLevel());
         lqw.eq(bo.getBusinessType() != null, SalesAnnualFinalization::getBusinessType, bo.getBusinessType());
+        lqw.eq(bo.getFinalizationType() != null, SalesAnnualFinalization::getFinalizationType, bo.getFinalizationType());
         lqw.eq(StrUtil.isNotBlank(bo.getProductSupport()), SalesAnnualFinalization::getProductSupport, bo.getProductSupport());
         return lqw;
     }
@@ -85,30 +98,31 @@ public class SalesAnnualFinalizationServiceImpl implements ISalesAnnualFinalizat
      */
     @Override
     public Boolean insertByBo(SalesAnnualFinalizationBo bo) {
+        autoFillDept(bo);
         SalesAnnualFinalization add = BeanUtil.toBean(bo, SalesAnnualFinalization.class);
         validEntityBeforeSave(add);
 
         if (add.getProjectNo() == null || add.getProjectNo().isEmpty()) {
             add.setProjectNo(SequenceUtils.nextPaddedIdStr(PROJECT_NO_KEY, Duration.ofDays(3650), 6));
         }
-        // 恢复默认值赋值,因为当前连接的数据库仍然提示没有默认值
-        if (add.getBiddingType() == null) {
-            add.setBiddingType(1);
-        }
-        if (add.getProjectStatus() == null) {
-            add.setProjectStatus(1);
-        }
-        if (add.getBidBondStatus() == null) {
-            add.setBidBondStatus(0);
-        }
-        if (add.getIsNoticeAdvance() == null) {
-            add.setIsNoticeAdvance(0);
-        }
 
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
             bo.setId(add.getId());
             operationLogService.recordLog(2, String.valueOf(add.getId()), 1, null, "年度入围", add.getProjectName());
+            
+            // 自动将负责人加入团队成员
+            if (add.getLeader() != null) {
+                TeamMemberBo memberBo = new TeamMemberBo();
+                memberBo.setDataType(2); // 年度入围
+                memberBo.setObjectNo(String.valueOf(add.getId()));
+                memberBo.setUserNo(add.getLeader());
+                memberBo.setRealName(add.getLeaderName());
+                memberBo.setRoleCode(CustomerConstants.TEAM_ROLE_LEADER);
+                memberBo.setUpdateAccredit(1);
+                memberBo.setIzManager(1);
+                teamMemberService.insertOrUpdateMember(memberBo);
+            }
         }
         return flag;
     }
@@ -118,6 +132,7 @@ public class SalesAnnualFinalizationServiceImpl implements ISalesAnnualFinalizat
      */
     @Override
     public Boolean updateByBo(SalesAnnualFinalizationBo bo) {
+        autoFillDept(bo);
         SalesAnnualFinalization oldData = baseMapper.selectById(bo.getId());
         SalesAnnualFinalization update = BeanUtil.toBean(bo, SalesAnnualFinalization.class);
         validEntityBeforeSave(update);
@@ -126,10 +141,37 @@ public class SalesAnnualFinalizationServiceImpl implements ISalesAnnualFinalizat
             if (!ObjectUtil.equals(oldData.getProjectStatus(), bo.getProjectStatus())) {
                 operationLogService.recordLog(2, String.valueOf(bo.getId()), 2, null, "项目状态", String.valueOf(bo.getProjectStatus()));
             }
+            // 同步负责人到团队成员
+            if (update.getLeader() != null) {
+                TeamMemberBo memberBo = new TeamMemberBo();
+                memberBo.setDataType(2);
+                memberBo.setObjectNo(String.valueOf(update.getId()));
+                memberBo.setUserNo(update.getLeader());
+                memberBo.setRealName(update.getLeaderName());
+                memberBo.setRoleCode(CustomerConstants.TEAM_ROLE_LEADER);
+                memberBo.setUpdateAccredit(1);
+                memberBo.setIzManager(1);
+                teamMemberService.insertOrUpdateMember(memberBo);
+            }
         }
         return flag;
     }
 
+    /**
+     * 自动填充部门
+     */
+    private void autoFillDept(SalesAnnualFinalizationBo bo) {
+        if (StrUtil.isBlank(bo.getDeptNo()) && bo.getLeader() != null) {
+            List<RemoteUserVo> remoteUserVos = remoteUserService.selectListByIds(List.of(bo.getLeader()));
+            if (CollUtil.isNotEmpty(remoteUserVos)) {
+                RemoteUserVo userVo = remoteUserVos.get(0);
+                if (userVo.getDeptId() != null) {
+                    bo.setDeptNo(String.valueOf(userVo.getDeptId()));
+                }
+            }
+        }
+    }
+
     /**
      * 保存前校验
      */
@@ -147,4 +189,67 @@ public class SalesAnnualFinalizationServiceImpl implements ISalesAnnualFinalizat
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+
+    /**
+     * 转移年度入围项目
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean transfer(SalesAnnualFinalizationBo bo) {
+        List<Long> ids = bo.getIds();
+        if (ids == null || ids.isEmpty()) {
+            if (bo.getId() == null) return false;
+            ids = List.of(bo.getId());
+        }
+        
+        Long newLeaderId = bo.getNewLeaderId() != null ? bo.getNewLeaderId() : bo.getLeader();
+        if (newLeaderId == null) return false;
+
+        String leaderName = bo.getLeaderName();
+        if (StrUtil.isBlank(leaderName)) {
+            List<RemoteUserVo> users = remoteUserService.selectListByIds(List.of(newLeaderId));
+            if (CollUtil.isNotEmpty(users)) {
+                leaderName = users.get(0).getNickName();
+            }
+        }
+        
+        boolean result = true;
+        for (Long id : ids) {
+            SalesAnnualFinalization oldData = baseMapper.selectById(id);
+            if (oldData == null) continue;
+            
+            Long oldLeaderId = oldData.getLeader();
+            
+            // 如果不保留原负责人,且原负责人与新负责人不同,则从团队中移除原负责人
+            if (Boolean.FALSE.equals(bo.getKeepAsMember()) && oldLeaderId != null && !oldLeaderId.equals(newLeaderId)) {
+                teamMemberService.removeMember(2, String.valueOf(id), oldLeaderId);
+            }
+
+            SalesAnnualFinalization update = new SalesAnnualFinalization();
+            update.setId(id);
+            update.setLeader(newLeaderId);
+            update.setLeaderName(leaderName);
+            boolean success = baseMapper.updateById(update) > 0;
+            result = result && success;
+            if (success) {
+                // 同步新负责人到团队成员
+                TeamMemberBo memberBo = new TeamMemberBo();
+                memberBo.setDataType(2); // 年度入围
+                memberBo.setObjectNo(String.valueOf(id));
+                memberBo.setUserNo(newLeaderId);
+                memberBo.setRealName(leaderName);
+                memberBo.setRoleCode(CustomerConstants.TEAM_ROLE_LEADER);
+                memberBo.setUpdateAccredit(1);
+                memberBo.setIzManager(1);
+                teamMemberService.insertOrUpdateMember(memberBo);
+
+                // 记录日志
+                operationLogService.recordLog(2, String.valueOf(id), CustomerConstants.ACTION_TYPE_TRANSFER, null, "转移了年度入围项目", leaderName);
+            }
+        }
+
+        return result;
+    }
+
+
 }

+ 15 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/TeamMemberServiceImpl.java

@@ -181,4 +181,19 @@ public class TeamMemberServiceImpl implements ITeamMemberService {
             return insertMember(bo);
         }
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean removeMember(Integer dataType, String objectNo, Long userNo) {
+        TeamMemberVo existing = baseMapper.selectByObjectNoAndUserNo(objectNo, userNo);
+        if (existing != null) {
+            boolean flag = baseMapper.deleteById(existing.getId()) > 0;
+            if (flag) {
+                operationLogService.recordLog(dataType, objectNo, CustomerConstants.ACTION_TYPE_DELETE, null, CustomerConstants.MODULE_TEAM_MEMBER, existing.getRealName());
+            }
+            return flag;
+        }
+        return false;
+    }
 }
+