Prechádzať zdrojové kódy

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper

QuYueTing 5 mesiacov pred
rodič
commit
b528e9ef4b
13 zmenil súbory, kde vykonal 343 pridanie a 53 odobranie
  1. 106 13
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/BusinessOpportunityController.java
  2. 9 8
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/SalesOrderController.java
  3. 6 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/BusinessOpportunity.java
  4. 7 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Stage.java
  5. 10 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/BusinessOpportunityServiceImpl.java
  6. 54 16
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ContractServiceImpl.java
  7. 14 5
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/BusinessOpportunityMapper.xml
  8. 1 1
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/ContractMapper.xml
  9. 3 1
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/StageMapper.xml
  10. 5 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/DeviceLogController.java
  11. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/DeviceLogService.java
  12. 115 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DeviceLogServiceImpl.java
  13. 11 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

+ 106 - 13
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/BusinessOpportunityController.java

@@ -8,10 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.management.platform.entity.*;
-import com.management.platform.mapper.BusinessOpportunityMapper;
-import com.management.platform.mapper.ClueMapper;
-import com.management.platform.mapper.SysFormMapper;
-import com.management.platform.mapper.UserMapper;
+import com.management.platform.mapper.*;
 import com.management.platform.service.*;
 import com.management.platform.service.impl.ExcelExportServiceImpl;
 import com.management.platform.util.HttpRespMsg;
@@ -63,6 +60,8 @@ public class BusinessOpportunityController {
     private BusinessOpportunityMapper boMapper;
     @Resource
     private BusinessOpportunityMapper businessOpportunityMapper;
+    @Resource
+    private ActionLogMapper actionLogMapper;
 
     @RequestMapping("getAll")
     public Object getAll(HttpServletRequest request) {
@@ -246,6 +245,14 @@ public class BusinessOpportunityController {
             bo.setUserId(user.getId());
             bo.setCreateTime(new Date());
             bo.setIsDelete(0);
+            QueryWrapper<BusinessOpportunity> queryWrapper = new QueryWrapper<>();
+            queryWrapper.eq("stage_id", bo.getStageId()).eq("is_delete",0).orderByDesc("seq").last("limit 1");
+            List<BusinessOpportunity> list = bOservice.list(queryWrapper);
+            if (list != null && list.size() > 0) {
+                bo.setSeq(list.get(0).getSeq()+1);
+            }else {
+                bo.setSeq(1);
+            }
             bOservice.insert(bo);
         }else {
             //修改
@@ -290,6 +297,78 @@ public class BusinessOpportunityController {
         return msg;
     }
 
+
+    @RequestMapping("/changeOrder")
+    public HttpRespMsg changeOrder(HttpServletRequest request,Integer id, Integer oldIndex, Integer newIndex, Integer oldStagesId, Integer newStagesId) {
+
+        HttpRespMsg msg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("Token"));
+        BusinessOpportunity curItem = new BusinessOpportunity();
+        curItem.setId(id);
+        if (!oldStagesId.equals(newStagesId)) {
+            //获取移动到的目标位置上一个数据的seq,计算当前任务的新seq
+            //跨stage移动,旧的stage上移除,切换stages后,旧的任务列表自动会重新排序,不需要再操作
+            curItem.setStageId(newStagesId);
+//            curItem.setStageValue(sy.getById(newStagesId).getStagesName());
+        }
+
+        QueryWrapper<BusinessOpportunity> queryWrapper = new QueryWrapper<BusinessOpportunity>();
+        int startSeq = 0;
+        if (newIndex > 0) {
+            int beforeItemIndex = 0;
+            if (oldStagesId.equals(newStagesId)) {
+                beforeItemIndex = newIndex > oldIndex?newIndex:newIndex-1;
+            } else {
+                //跨stages移动,相当于从下往上移动
+                beforeItemIndex = newIndex-1;
+            }
+            queryWrapper.eq("stage_id", newStagesId).eq("is_delete",0).orderByAsc("seq").last("limit " +beforeItemIndex+", 1");
+            List<BusinessOpportunity> list = bOservice.list(queryWrapper);
+            if (list.size() > 0) {
+                BusinessOpportunity beforeItem = list.get(0);
+                startSeq = beforeItem.getSeq() + 1;
+            } else {
+                startSeq = 1;
+            }
+        } else {
+            //移动到了第一个位置
+            startSeq = 1;
+        }
+
+        curItem.setSeq(startSeq);
+        //在新位置下面的包括原来占据新位置的,全部调整,从startSeq开始递增
+        queryWrapper = new QueryWrapper<BusinessOpportunity>();
+        queryWrapper.eq("stage_id", newStagesId).eq("is_delete",0).ge("seq", startSeq).orderByAsc("seq");
+        List<BusinessOpportunity> list = bOservice.list(queryWrapper);
+        if (list.size() > 0) {
+            List<BusinessOpportunity> batchList = new ArrayList<>();
+            for (BusinessOpportunity t:list) {
+                BusinessOpportunity item = new BusinessOpportunity();
+                item.setId(t.getId());
+                startSeq++;
+                item.setSeq(startSeq);
+                batchList.add(item);
+            }
+            bOservice.updateBatchById(batchList);
+        }
+
+        if (!newStagesId.equals(oldStagesId)){
+            curItem.setEditTime(new Date());
+            Stage stage = stageService.getOne(new QueryWrapper<Stage>().eq("id", newStagesId).eq("company_id", user.getCompanyId()));
+            ActionLog al = new ActionLog();
+            al.setCode("business");
+            al.setName("推进了阶段至" + stage.getName());
+            al.setCreatTime(new Date());
+            al.setUserId(user.getId());
+            al.setItemId(id);
+            actionLogMapper.insert(al);
+        }
+        bOservice.updateById(curItem);
+
+        return msg;
+    }
+
+
     @RequestMapping("list")
     public HttpRespMsg list(BusinessOpportunity bo, HttpServletRequest request) {
         HashMap<Object, Object> r = new HashMap<>();
@@ -322,27 +401,41 @@ public class BusinessOpportunityController {
     }
 
     @RequestMapping("getAllByStage")
-    public Object getAllByStage(HttpServletRequest request) {
+    public Object getAllByStage(BusinessOpportunity bo,HttpServletRequest request) {
         User user = userMapper.selectById(request.getHeader("Token"));
+        bo.setIsDelete(0);
+        bo.setCompanyId(user.getCompanyId());
+        bo.setUserId(user.getId());
+        bo.setEndTime(bo.getEndTime() + " 23:59:59");
+        bo.setPageFrom(null);
+        bo.setPageIndex(null);
         List<BusinessOpportunity> list = new ArrayList<>();
         boolean isAll = sysFunctionService.hasPriviledge(user.getRoleId(), "查看全部商机");
         boolean isNotAll = sysFunctionService.hasPriviledge(user.getRoleId(), "查看负责部门商机");
         if (isAll) {
-            list = boMapper.getAllList(user.getCompanyId());
+            list = bOservice.getAll(bo);
         } else if (isNotAll) {
-            list = boMapper.getAllList1(user);
+            list = bOservice.getAll1(bo, user);
         } else {
-            list = boMapper.getAllList2(user);
+            list = bOservice.getAll2(bo, user);
         }
+
         HttpRespMsg msg = new HttpRespMsg();
-        List<Stage> stageList = stageService.list(new QueryWrapper<Stage>().eq("company_id", user.getCompanyId()));
-        HashMap<String, Object> map = new HashMap<>();
+        List<Stage> stageList = stageService.list(new QueryWrapper<Stage>().eq("company_id", user.getCompanyId()).orderByAsc("seq"));
+
+        List<HashMap<String, Object>> mapList = new ArrayList<>();
         for (Stage stage : stageList) {
             List<BusinessOpportunity> collect = list.stream().filter(l -> l.getStageId() != null && l.getStageId().equals(stage.getId())).collect(Collectors.toList());
-            HashMap<String, Object> hashMap = new HashMap<>();
-            map.put(stage.getName(),collect);
+            collect=collect.stream().sorted(Comparator.comparing(BusinessOpportunity::getSeq)).collect(Collectors.toList());
+            HashMap<String, Object> map = new HashMap<>();
+            map.put("id", stage.getId());
+            map.put("label",stage.getName());
+            map.put("length",collect.size());
+            map.put("list",collect);
+            map.put("color",stage.getColor());
+            mapList.add(map);
         }
-        msg.setData(map);
+        msg.setData(mapList);
         return msg;
 
     }

+ 9 - 8
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/controller/SalesOrderController.java

@@ -355,16 +355,17 @@ public class SalesOrderController {
         List<Task> taskList = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getOrderId, id));
         taskList.forEach(p->{
             String executorIds = p.getExecutorId();
-            String[] split = executorIds.split(",");
-            List<String> executorNameList=new ArrayList<>();
-            for (String s : split) {
-                Optional<User> user = userList.stream().filter(u -> u.getId().equals(s)).findFirst();
-                if(user.isPresent()){
-                    executorNameList.add(user.get().getName());
+            if (executorIds!=null && !StringUtils.isEmpty(executorIds)) {
+                String[] split = executorIds.split(",");
+                List<String> executorNameList=new ArrayList<>();
+                for (String s : split) {
+                    Optional<User> user = userList.stream().filter(u -> u.getId().equals(s)).findFirst();
+                    if(user.isPresent()){
+                        executorNameList.add(user.get().getName());
+                    }
                 }
+                p.setExecutorNames(executorNameList);
             }
-//            String collect = executorNameList.stream().map(i -> i).collect(Collectors.joining(","));
-            p.setExecutorNames(executorNameList);
         });
         msg.setData(taskList);
         return msg;

+ 6 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/BusinessOpportunity.java

@@ -22,7 +22,7 @@ import org.springframework.format.annotation.DateTimeFormat;
  * </p>
  *
  * @author Seyason
- * @since 2024-03-22
+ * @since 2024-12-03
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -192,6 +192,11 @@ public class BusinessOpportunity extends Model<BusinessOpportunity> {
     @TableField(exist = false)
     private List<UploadFile> uploadFilePList;
 
+    /**
+     * 排序
+     */
+    @TableField("seq")
+    private Integer seq;
 
 
     @Override

+ 7 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Stage.java

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2024-03-29
+ * @since 2024-12-03
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -56,6 +56,12 @@ public class Stage extends Model<Stage> {
     @TableField("is_finish")
     private Integer isFinish;
 
+    /**
+     * 颜色
+     */
+    @TableField("color")
+    private String color;
+
 
     @Override
     protected Serializable pkVal() {

+ 10 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/BusinessOpportunityServiceImpl.java

@@ -710,7 +710,16 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
 
     @Override
     public void saveStage(BusinessOpportunity bo, User user) {
-        bOMapper.update(bo, new UpdateWrapper<BusinessOpportunity>().eq("id", bo.getId()).set("Stage_Id", bo.getStageId()).set("edit_time",new Date()));
+        QueryWrapper<BusinessOpportunity> queryWrapper = new QueryWrapper<BusinessOpportunity>().eq("stage_id", bo.getStageId()).eq("is_delete", 0).orderByDesc("seq").last("limit 1");
+        List<BusinessOpportunity> list = bOMapper.selectList(queryWrapper);
+        if (list.isEmpty()){
+            bo.setSeq(1);
+        }else {
+            bo.setSeq(list.get(0).getSeq()+1);
+        }
+        bOMapper.update(bo, new UpdateWrapper<BusinessOpportunity>().eq("id", bo.getId())
+                .set("Stage_Id", bo.getStageId()).set(bo.getSeq()!=null,"seq",bo.getSeq())
+                .set("edit_time",new Date()));
         ActionLog al = new ActionLog();
         al.setCode("business");
         al.setName("推进了阶段至" + bo.getStageValue());

+ 54 - 16
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ContractServiceImpl.java

@@ -80,6 +80,8 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
     private ContractLogMapper contractLogMapper;
     @Resource
     private InformationMapper informationMapper;
+    @Resource
+    private SysDictMapper sysDictMapper;
     @Value(value = "${upload.path}")
     private String path;
     @Autowired
@@ -87,6 +89,8 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
     @Autowired
     private ContractPayCustomizedMapper contractPayCustomizedMapper;
 
+
+
     /**
      * 分页查询合同
      * @param request
@@ -564,7 +568,9 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
                 return msg;
             }
             List<Contract> contractList = contractMapper.selectList(new QueryWrapper<Contract>().eq("company_id", companyId));
-            List<ContractType> typeList = contractTypeMapper.selectList(new QueryWrapper<ContractType>().eq("company_id", companyId));
+//            List<ContractType> typeList = contractTypeMapper.selectList(new QueryWrapper<ContractType>().eq("company_id", companyId));
+            List<SysDict> sysDictList = sysDictMapper.selectList(new LambdaQueryWrapper<SysDict>().eq(SysDict::getCompanyId, companyId).eq(SysDict::getCode, "ContractType").orderByAsc(SysDict::getSeq));
+
             ArrayList<Contract> saveContract = new ArrayList<>();
             int dataIndex = 1;
             for (int rowIndex = 1; rowIndex <= rowNum; rowIndex++) {
@@ -591,10 +597,42 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
                 }
                 String No = row.getCell(0)==null?null:row.getCell(0).getStringCellValue();
                 String name = row.getCell(1)==null?null:row.getCell(1).getStringCellValue();
-                String startDate = row.getCell(2)==null?null:row.getCell(2).getStringCellValue();
-                String endDate = row.getCell(3)==null?null:row.getCell(3).getStringCellValue();
-                String amounts = row.getCell(4)==null?null:row.getCell(4).getStringCellValue();
-                String type = row.getCell(5)==null?null:row.getCell(5).getStringCellValue();
+                LocalDate startDate = null;
+                LocalDate endDate = null;
+                if(row.getCell(4) != null && row.getCell(4).getCellTypeEnum() != CellType.BLANK){
+                    if(!StringUtils.isEmpty(row.getCell(4).getStringCellValue())){
+                        try {
+                            int count = Integer.parseInt(row.getCell(4).getStringCellValue());
+                            // Excel中的日期序列号的基准日期是1900年1月1日
+                            LocalDate baseDate = LocalDate.of(1900, 1, 1);
+                            LocalDate date = baseDate.plusDays(count - 2); // Excel的基准日期是1900年1月0日,所以需要减去2天
+                            startDate = date;
+
+                        } catch (Exception e) {
+                            System.out.println("日期时间格式不正确,应该是yyyy/MM/dd" );
+                            msg.setError("日期时间格式不正确,应该是yyyy/MM/dd");
+                            return msg;
+                        }
+                    }
+                }
+                if(row.getCell(5) != null && row.getCell(5).getCellTypeEnum() != CellType.BLANK){
+                    if(!StringUtils.isEmpty(row.getCell(5).getStringCellValue())){
+                        try {
+                            int count = Integer.parseInt(row.getCell(5).getStringCellValue());
+                            // Excel中的日期序列号的基准日期是1900年1月1日
+                            LocalDate baseDate = LocalDate.of(1900, 1, 1);
+                            LocalDate date = baseDate.plusDays(count - 2); // Excel的基准日期是1900年1月0日,所以需要减去2天
+                            endDate = date;
+
+                        } catch (Exception e) {
+                            System.out.println("日期时间格式不正确,应该是yyyy/MM/dd" );
+                            msg.setError("日期时间格式不正确,应该是yyyy/MM/dd");
+                            return msg;
+                        }
+                    }
+                }
+                String amounts = row.getCell(2)==null?null:row.getCell(2).getStringCellValue();
+                String type = row.getCell(3)==null?null:row.getCell(3).getStringCellValue();
                 String remarks = row.getCell(6)==null?null:row.getCell(6).getStringCellValue();
                 Contract item = new Contract();
                 //检查合同编号是否存在
@@ -622,8 +660,8 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
                 //检查合同类型是否存在
                 Integer typeId = null;
                 if (StringUtils.isNotBlank(type)){
-                    for (ContractType contractType : typeList) {
-                        if (contractType.getTypeName().equals(type)){
+                    for (SysDict contractType : sysDictList) {
+                        if (contractType.getName().equals(type)){
                             TypeExists = true;
                             typeId = contractType.getId();
                             break;
@@ -643,13 +681,11 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
                 item.setStatus(1);
                 //时间转化
                 DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-M-d");
-                if (StringUtils.isNotBlank(startDate)){
-                    LocalDate start = LocalDate.parse(startDate, dtf);
-                    item.setStartDate(start);
+                if (startDate!=null){
+                    item.setStartDate(startDate);
                 }
-                if (StringUtils.isNotBlank(endDate)){
-                    LocalDate end = LocalDate.parse(endDate, dtf);
-                    item.setEndDate(end);
+                if (endDate!=null){
+                    item.setEndDate(endDate);
                 }
                 if (StringUtils.isNotBlank(amounts) && Double.parseDouble(amounts) <= 0 ){
                     //第{0}行金额不可为负数
@@ -771,7 +807,9 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
                 return msg;
             }
             List<Contract> contractList = contractMapper.selectList(new QueryWrapper<Contract>().eq("company_id", companyId));
-            List<ContractType> typeList = contractTypeMapper.selectList(new QueryWrapper<ContractType>().eq("company_id", companyId));
+//            List<ContractType> typeList = contractTypeMapper.selectList(new QueryWrapper<ContractType>().eq("company_id", companyId));
+            List<SysDict> sysDictList = sysDictMapper.selectList(new LambdaQueryWrapper<SysDict>().eq(SysDict::getCompanyId, companyId).eq(SysDict::getCode, "ContractType").orderByAsc(SysDict::getSeq));
+
             //获取二级分类列表
             List<ContractTypeSec> secTypeList = contractTypeSecMapper.selectList(new QueryWrapper<ContractTypeSec>().eq("company_id", companyId));
             ArrayList<Contract> saveContract = new ArrayList<>();
@@ -914,8 +952,8 @@ public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract> i
                 //检查合同类型是否存在
                 Integer typeId = null;
                 if (StringUtils.isNotBlank(type)){
-                    for (ContractType contractType : typeList) {
-                        if (contractType.getTypeName().equals(type)){
+                    for (SysDict contractType : sysDictList) {
+                        if (contractType.getName().equals(type)){
                             TypeExists = true;
                             typeId = contractType.getId();
                             break;

+ 14 - 5
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/BusinessOpportunityMapper.xml

@@ -9,7 +9,6 @@
         <result column="name" property="name" />
         <result column="contacts_id" property="contactsId" />
         <result column="customer_id" property="customerId" />
-        <result column="product_id" property="productId" />
         <result column="amount_of_money" property="amountOfMoney" />
         <result column="expected_transaction_date" property="expectedTransactionDate" />
         <result column="stage_id" property="stageId" />
@@ -24,11 +23,14 @@
         <result column="plate3" property="plate3" />
         <result column="plate4" property="plate4" />
         <result column="plate5" property="plate5" />
+        <result column="clue_id" property="clueId" />
+        <result column="reason" property="reason" />
+        <result column="seq" property="seq" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, company_id, name, contacts_id, customer_id,  amount_of_money, expected_transaction_date, stage_id, create_time, edit_time, creator_id, incharger_id, remark, is_delete, plate1, plate2, plate3, plate4, plate5
+        id, company_id, name, contacts_id, customer_id,  amount_of_money, expected_transaction_date, stage_id, create_time, edit_time, creator_id, incharger_id, remark, is_delete,seq, plate1, plate2, plate3, plate4, plate5
     </sql>
     <select id="selectAllList" resultType="com.management.platform.entity.BusinessOpportunity">
         select
@@ -64,7 +66,10 @@
             and id in (select business_id from business_product where product_id = #{productId})
         </if>
         ORDER BY id DESC
-        limit #{pageIndex},#{pageFrom}
+        <if test="pageIndex!=null and pageFrom !=null">
+            limit #{pageIndex},#{pageFrom}
+        </if>
+
     </select>
     <select id="getTotal" resultType="java.lang.Integer">
         select
@@ -131,7 +136,9 @@
             and id in (select business_id from business_product where product_id = #{bo.productId})
         </if>
         ORDER BY id DESC
-        limit #{bo.pageIndex},#{bo.pageFrom}
+        <if test="bo.pageIndex!=null and bo.pageFrom !=null">
+            limit #{bo.pageIndex},#{bo.pageFrom}
+        </if>
     </select>
     <select id="getTotal1" resultType="java.lang.Integer">
         select
@@ -199,7 +206,9 @@
             and id in (select business_id from business_product where product_id =#{bo.productId})
         </if>
         ORDER BY id DESC
-        limit #{bo.pageIndex},#{bo.pageFrom}
+        <if test="bo.pageIndex!=null and bo.pageFrom !=null">
+            limit #{bo.pageIndex},#{bo.pageFrom}
+        </if>
     </select>
     <select id="getTotal2" resultType="java.lang.Integer">
         select

+ 1 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/ContractMapper.xml

@@ -66,7 +66,7 @@
         <if test="customerOrg!=null">
             and cc.customer_org like  CONCAT('%', #{customerOrg}, '%')
         </if>
-        order by contract.number desc
+        order by contract.id desc
         <if test="pageStart!=null and pageSize!=null">
             limit #{pageStart},#{pageSize}
         </if>

+ 3 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/StageMapper.xml

@@ -9,11 +9,13 @@
         <result column="plan" property="plan" />
         <result column="seq" property="seq" />
         <result column="is_finish" property="isFinish" />
+        <result column="company_id" property="companyId" />
+        <result column="color" property="color" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, name, plan, seq, is_finish
+        id, name, plan, seq, is_finish, company_id, color
     </sql>
 
 </mapper>

+ 5 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/DeviceLogController.java

@@ -74,5 +74,10 @@ public class DeviceLogController {
         return deviceLogService.exportDeviceTimeCost(request,startDate, endDate,projectId);
     }
 
+    @RequestMapping("/exportDeviceTimeCostByMonth")
+    public HttpRespMsg exportDeviceTimeCostByMonth(HttpServletRequest request,String date, Integer projectId) {
+        return deviceLogService.exportDeviceTimeCostByMonth(request,date,projectId);
+    }
+
 }
 

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/DeviceLogService.java

@@ -27,4 +27,6 @@ public interface DeviceLogService extends IService<DeviceLog> {
     HttpRespMsg getDeviceTimeCost(HttpServletRequest request,String startDate, String endDate, Integer projectId);
 
     HttpRespMsg exportDeviceTimeCost(HttpServletRequest request, String startDate, String endDate, Integer projectId);
+
+    HttpRespMsg exportDeviceTimeCostByMonth(HttpServletRequest request, String date, Integer projectId);
 }

+ 115 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DeviceLogServiceImpl.java

@@ -25,6 +25,7 @@ import java.math.RoundingMode;
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.YearMonth;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
@@ -370,4 +371,118 @@ public class DeviceLogServiceImpl extends ServiceImpl<DeviceLogMapper, DeviceLog
         }
         return httpRespMsg;
     }
+
+    @Override
+    public HttpRespMsg exportDeviceTimeCostByMonth(HttpServletRequest request, String date, Integer projectId) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        String[] strings = date.split("-");
+        int year = Integer.parseInt(strings[0]);
+        int month = Integer.parseInt(strings[1]);
+        YearMonth yearMonth = YearMonth.of((year), month);
+        int daysInMonth = yearMonth.lengthOfMonth();
+
+        // 获取该月份的第一天
+        String startDate = String.format("%04d-%02d-01", year, month);
+        // 获取下个月的第一天
+        LocalDate lastDate = LocalDate.of(year, month, 1).plusDays(LocalDate.of(year, month, 1).lengthOfMonth() - 1);
+        String endDate = String.format("%04d-%02d-%02d", year, month, lastDate.getDayOfMonth());
+
+        User targetUser = userMapper.selectById(request.getHeader("Token"));
+        Integer companyId = targetUser.getCompanyId();
+        List<Map<String, Object>> sumProjectList =deviceLogMapper.selectListGroupByProject(companyId,startDate,endDate,projectId);
+        List<Device> deviceList = deviceMapper.selectList(new QueryWrapper<Device>().eq("company_id", companyId));
+        List<DeviceLog> deviceLogs = deviceLogMapper.selectList(new QueryWrapper<DeviceLog>().between("create_date", startDate, endDate).isNotNull("end_time"));
+
+        ArrayList<List<String>> allList = new ArrayList<>();
+        List<String> headList = new ArrayList<String>();
+        headList.add("项目编号");
+        headList.add("项目名称");
+        headList.add("设备编号");
+        headList.add("设备名称");
+        headList.add("成本(元)");
+        headList.add("月度总工时(h)");
+        for (int i = 1; i <= daysInMonth; i++) {
+            headList.add(i+"日");
+        }
+        allList.add(headList);
+
+        if (!sumProjectList.isEmpty()){
+            for (Map<String, Object> sum : sumProjectList) {
+                List<String> rowSum = new ArrayList<String>();
+
+                rowSum.add(sum.get("projectCode")==null?"":sum.get("projectCode").toString());
+                rowSum.add(sum.get("projectName")==null?"":sum.get("projectName").toString());
+                rowSum.add("");
+                rowSum.add("");
+                rowSum.add(sum.get("costMoney")==null?"":sum.get("costMoney").toString());
+                rowSum.add(sum.get("cost")==null?"":sum.get("cost").toString());
+                for (int i = 1; i <= daysInMonth; i++) {
+                    int finalI = i;
+                    double useTime = deviceLogs.stream()
+                            .filter(dl -> dl.getProjectId().equals(sum.get("id"))
+                                    && dl.getCreateDate().getYear() == year
+                                    && dl.getCreateDate().getMonthValue() == month
+                                    && dl.getCreateDate().getDayOfMonth() == finalI)
+                            .mapToDouble(DeviceLog::getUseTime).sum();
+                    rowSum.add(useTime==0?"":BigDecimal.valueOf(useTime).setScale(2, RoundingMode.HALF_UP).toString());
+
+                }
+                allList.add(rowSum);
+
+
+                String idProject = sum.get("id").toString();
+                List<Integer> deviceIds = deviceLogs.stream().filter(dl -> dl.getProjectId().toString().equals(idProject)).map(DeviceLog::getDeviceId).distinct().collect(Collectors.toList());
+                if (!deviceIds.isEmpty()){
+                    for (Integer deviceId : deviceIds) {
+                        List<String> row = new ArrayList<String>();
+                        row.add("");
+                        row.add("");
+                        List<Device> deviceList1 = deviceList.stream().filter(d -> d.getId().equals(deviceId)).collect(Collectors.toList());
+                        if (!deviceList1.isEmpty()) {
+                            Device device = deviceList1.get(0);
+                            row.add(device.getDeviceCode());
+                            row.add(device.getDeviceName());
+                        }else {
+                            row.add("");
+                            row.add("");
+                        }
+                        BigDecimal usageCost = deviceLogs.stream()
+                                .filter(dl -> dl.getProjectId().toString().equals(idProject) && dl.getDeviceId().equals(deviceId)&&dl.getUsageCost()!=null)
+                                .map(DeviceLog::getUsageCost)
+                                .reduce(BigDecimal.ZERO, BigDecimal::add);
+                        double useTime = deviceLogs.stream()
+                                .filter(dl -> dl.getProjectId().toString().equals(idProject) && dl.getDeviceId().equals(deviceId))
+                                .mapToDouble(DeviceLog::getUseTime).sum();
+                        row.add(usageCost.toString());
+                        row.add(useTime==0?"":BigDecimal.valueOf(useTime).setScale(2, RoundingMode.HALF_UP).toString());
+
+                        for (int i = 1; i <= daysInMonth; i++) {
+                            int finalI = i;
+                            Optional<DeviceLog> first = deviceLogs.stream()
+                                    .filter(dl -> dl.getProjectId().toString().equals(idProject)
+                                            && dl.getDeviceId().equals(deviceId)
+                                            && dl.getCreateDate().getYear() == year
+                                            && dl.getCreateDate().getMonthValue() == month
+                                            && dl.getCreateDate().getDayOfMonth() == finalI).findFirst();
+                            if (first.isPresent()) {
+                                Double useTime1 = first.get().getUseTime();
+                                row.add(useTime1==null?"":BigDecimal.valueOf(useTime1).setScale(2, RoundingMode.HALF_UP).toString());
+                            }else {
+                                row.add("");
+                            }
+                        }
+                        allList.add(row);
+                    }
+                }
+            }
+        }
+
+        String fileName = "设备成本导出"+System.currentTimeMillis();
+        try {
+            return excelExportService.exportGeneralExcelByTitleAndList(null,null,fileName,allList, path);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return httpRespMsg;
+    }
 }

+ 11 - 6
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -441,13 +441,18 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
 
             //抽取出来项目编号,项目名称
             List<Map<String, Object>> uniqueDataList = dataList.stream()
-                    .distinct() // 确保唯一性
-                    .map(item -> ImmutableMap.of(
-                            "id", item.get("id"),
-                            "projectCode", item.get("projectCode"),
-                            "projectName", item.get("projectName")
+                    .collect(Collectors.toMap(
+                            item -> item.get("id"), // 根据 id 去重
+                            item -> ImmutableMap.of(
+                                    "id", item.get("id"),
+                                    "projectCode", item.get("projectCode"),
+                                    "projectName", item.get("projectName")
+                            ),
+                            (existing, replacement) -> existing // 如果重复,保留第一个
                     ))
-                    .collect(Collectors.toList());
+                    .values() // 获取去重后的值
+                    .stream() // 转换为流
+                    .collect(Collectors.toList()); // 收集到 List
 
             //查询项目对应人员填写的每次工时时长
             List<Map<String, Object>> dataDetailList = projectMapper.getTimeCostProjectUserWorkTime(companyId,startDate, endDate);