钱惠东 5 днів тому
батько
коміт
d6c5bdc1fe

+ 2 - 11
RuoYi-Vue-fast-master/src/main/java/com/ruoyi/project/business/controller/board/BoardController.java

@@ -144,17 +144,8 @@ public class BoardController extends BaseController {
      **/
     @Log(title = "新代理商成单统计", businessType = BusinessType.EXPORT)
     @PostMapping("/exportAgentCompleteOrder")
-    public void exportCustomerCompleteOrder(HttpServletResponse response, AgentCompleteOrder agentCompleteOrder ) {
-        List<AgentCompleteOrderVo> list = tcProjectService.getAgentCompleteOrderList(agentCompleteOrder);
-        list.stream()
-                .filter(item -> item.getAgentId() == 0)
-                .forEach(item -> item.setAgentName("总部"));
-        ExcelUtil<AgentCompleteOrderVo> util = new ExcelUtil<AgentCompleteOrderVo>(AgentCompleteOrderVo.class);
-        String[] finalColumns = {"areaName"};
-        if (!agentCompleteOrder.isShowColumn()){
-            util.hideColumn(finalColumns);
-        }
-        util.exportExcel(response, list, MessageUtils.message("account.exportSheetName"));
+    public void exportCustomerCompleteOrder(AgentCompleteOrder agentCompleteOrder ) {
+        tcProjectService.exportCustomerCompleteOrder(agentCompleteOrder);
     }
 
     /**

+ 1 - 0
RuoYi-Vue-fast-master/src/main/java/com/ruoyi/project/business/domain/vo/board/AgentCompleteOrder.java

@@ -25,6 +25,7 @@ public class AgentCompleteOrder {
 
     /** 年份 */
     private String yearParam;
+    private List<Integer> weeks;
     private String language;
     // 带逗号
     private String permissionChar;

+ 0 - 2
RuoYi-Vue-fast-master/src/main/java/com/ruoyi/project/business/domain/vo/board/AgentTargetProgressVo.java

@@ -39,8 +39,6 @@ public class AgentTargetProgressVo {
     /** 代理商 */
     private Long agentId;
 
-    private List<AgentTargetProgressVo> agentTargetProgressVoList;
-
     /** 年份 */
     private String yearParam;
 

+ 5 - 2
RuoYi-Vue-fast-master/src/main/java/com/ruoyi/project/business/mapper/TcProjectMapper.java

@@ -3,11 +3,13 @@ package com.ruoyi.project.business.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import java.time.LocalDateTime;
 import java.util.List;
+import java.util.Map;
 
 import com.ruoyi.project.business.domain.TcProject;
 import com.ruoyi.project.business.domain.TcProjectForRelated;
 import com.ruoyi.project.business.domain.vo.board.*;
 import com.ruoyi.project.business.domain.vo.selectParam.ProjectParam;
+import org.apache.ibatis.annotations.MapKey;
 import org.apache.ibatis.annotations.Param;
 
 /**
@@ -136,6 +138,7 @@ public interface TcProjectMapper extends BaseMapper<TcProject> {
     List<AgentCompleteOrderVo> getAgentCompleteOrderList(AgentCompleteOrder agentCompleteOrder);
     List<AccountCompleteOrderVo> getAccountCompleteOrderList(AgentCompleteOrder agentCompleteOrder);
 
-    List<AgentTargetProgressVo> getAgentTargetProgressList(AgentCompleteOrder agentCompleteOrder);
-    List<AgentTargetProgressVo> getAgentTargetProgressListSub(AgentTargetProgressVo agentTargetProgressVo);
+    @MapKey("agentId")
+    List<Map<String, Object>> getAgentTargetProgressList(AgentCompleteOrder agentCompleteOrder);
+
 }

+ 5 - 1
RuoYi-Vue-fast-master/src/main/java/com/ruoyi/project/business/service/ITcProjectService.java

@@ -11,6 +11,8 @@ import com.ruoyi.project.business.domain.vo.board.*;
 import com.ruoyi.project.business.domain.vo.project.ProjectExportVO;
 import com.ruoyi.project.business.domain.vo.selectParam.ProjectParam;
 import java.util.List;
+import java.util.Map;
+
 import org.springframework.data.util.Pair;
 
 /**
@@ -155,5 +157,7 @@ public interface ITcProjectService extends IService<TcProject> {
     List<AgentCompleteOrderVo> getAgentCompleteOrderList(AgentCompleteOrder agentCompleteOrder);
     List<AccountCompleteOrderVo> getAccountCompleteOrderList(AgentCompleteOrder agentCompleteOrder);
 
-    List<AgentTargetProgressVo> getAgentTargetProgressList(AgentCompleteOrder agentCompleteOrder);
+    List<Map<String, Object>> getAgentTargetProgressList(AgentCompleteOrder agentCompleteOrder);
+
+    void exportCustomerCompleteOrder(AgentCompleteOrder agentCompleteOrder);
 }

+ 126 - 35
RuoYi-Vue-fast-master/src/main/java/com/ruoyi/project/business/service/impl/TcProjectServiceImpl.java

@@ -1,18 +1,33 @@
 package com.ruoyi.project.business.service.impl;
 
 import static com.ruoyi.project.business.enums.account.AccountStatusEnum.CONVERTED_PROJECT;
+import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DatePattern;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.thread.ThreadUtil;
 import cn.hutool.core.util.IdUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.builder.ExcelWriterBuilder;
+import com.alibaba.excel.write.handler.SheetWriteHandler;
+import com.alibaba.excel.write.handler.WriteHandler;
+import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext;
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
+import com.alibaba.excel.write.merge.LoopMergeStrategy;
+import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.PageInfo;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import com.ruoyi.common.enums.DelFlag;
 import com.ruoyi.common.enums.ProjectStatus;
 import com.ruoyi.common.enums.SerialNumberPrefix;
@@ -22,13 +37,7 @@ import com.ruoyi.common.importExcel.excel.tempInfo.ProjectEquipmentInfo;
 import com.ruoyi.common.importExcel.excel.tempInfo.ProjectFromInfo;
 import com.ruoyi.common.importExcel.utils.ExcelUtils;
 import com.ruoyi.common.importExcel.utils.ExcelUtils.UploadResult;
-import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.common.utils.DictUtils;
-import com.ruoyi.common.utils.LocalUtils;
-import com.ruoyi.common.utils.MessageUtils;
-import com.ruoyi.common.utils.SecurityUtils;
-import com.ruoyi.common.utils.SpecialCharacterEscaper;
-import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.*;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.common.utils.email.BaseEmailEntity;
 import com.ruoyi.common.utils.email.EmailUtil;
@@ -66,23 +75,22 @@ import com.ruoyi.project.system.domain.SysDictData;
 import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.project.system.mapper.SysUserMapper;
 import com.ruoyi.project.system.service.ISysUserService;
+
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.text.DecimalFormat;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.*;
 import java.util.stream.Collectors;
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.MessageSource;
@@ -152,6 +160,9 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
     @Resource
     private ITcProjectEquipmentHistoryService tcProjectEquipmentHistoryService;
 
+    @Resource
+    private ITbCountryService tbCountryService;
+
     /**
      * 查询项目管理
      *
@@ -353,7 +364,7 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
         List<Long> projectIds = projects.stream().map(TcProject::getProjectId).collect(Collectors.toList());
 
         List<TcProject> quotationInfo =
-                CollectionUtils.isNotEmpty(projectIds) ? tcProjectMapper.selectQuotationInfo(projectIds)
+                isNotEmpty(projectIds) ? tcProjectMapper.selectQuotationInfo(projectIds)
                         : new ArrayList<>();
         Map<Long, List<TcProject>> quotationMap = quotationInfo.stream()
                 .collect(Collectors.groupingBy(TcProject::getProjectId));
@@ -361,7 +372,7 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
         for (TcProject project : projects) {
             project.setRowKey(String.valueOf(project.getProjectId()));
             List<TcProject> children = quotationMap.get(project.getProjectId());
-            if (CollectionUtils.isNotEmpty(children)) {
+            if (isNotEmpty(children)) {
                 if (children.size() > 1) {
                     for (TcProject child : children) {
                         BeanUtils.copyProperties(project, child, "rowKey", "elevatorNumber", "elevatorType",
@@ -402,7 +413,7 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
         }
         List<TcProject> tcProjects = tcProjectMapper.selectTcProjectListExport(tcProject);
         Map<Long,String> tcLeadForRelatedMap= new HashMap<>();
-        if(CollectionUtils.isNotEmpty(tcProjects)){
+        if(isNotEmpty(tcProjects)){
             List<Long> accountIdList = tcProjects.stream().map(item->item.getAccountId()).distinct() .collect(Collectors.toList());
             tcLeadForRelatedMap = suppleProjectExportVO(tcProjects.get(0).getLanguage(),accountIdList);
         }
@@ -581,7 +592,7 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
         tcProjectHistory.setVersion(newVersion);
         tcProjectHistoryService.insertTcProjectHistory(tcProjectHistory);
 
-        if (CollectionUtils.isNotEmpty(machineList)) {
+        if (isNotEmpty(machineList)) {
             List<TcProjectEquipmentHistory> equipmentHistories = machineList.stream().map(machine -> {
                 TcProjectEquipmentHistory history = new TcProjectEquipmentHistory();
                 BeanUtils.copyBeanProp(history, machine);
@@ -705,7 +716,7 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
         tcProjectHistory.setVersion(newVersion);
         tcProjectHistoryService.insertTcProjectHistory(tcProjectHistory);
 
-        if (CollectionUtils.isNotEmpty(machineList)) {
+        if (isNotEmpty(machineList)) {
             List<TcProjectEquipmentHistory> equipmentHistories = machineList.stream().map(machine -> {
                 TcProjectEquipmentHistory history = new TcProjectEquipmentHistory();
                 BeanUtils.copyBeanProp(history, machine);
@@ -775,7 +786,7 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
 
         List<TcProjectEquipment> machineList = tcProjectEquipmentService.list(Wrappers.<TcProjectEquipment>lambdaQuery()
                 .eq(TcProjectEquipment::getProjectId, exist.getProjectId()).eq(TcProjectEquipment::getDelFlag, DelFlagEnum.NORMAL.getValue()));
-        if (CollectionUtils.isNotEmpty(machineList)) {
+        if (isNotEmpty(machineList)) {
             List<TcProjectEquipmentHistory> equipmentHistories = machineList.stream().map(machine -> {
                 TcProjectEquipmentHistory history = new TcProjectEquipmentHistory();
                 BeanUtils.copyBeanProp(history, machine);
@@ -818,7 +829,7 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
 
         List<TcProjectEquipment> machineList = tcProjectEquipmentService.list(Wrappers.<TcProjectEquipment>lambdaQuery()
                 .eq(TcProjectEquipment::getProjectId, tcProject.getProjectId()).eq(TcProjectEquipment::getDelFlag, DelFlagEnum.NORMAL.getValue()));
-        if (CollectionUtils.isNotEmpty(machineList)) {
+        if (isNotEmpty(machineList)) {
             List<TcProjectEquipmentHistory> equipmentHistories = machineList.stream().map(machine -> {
                 TcProjectEquipmentHistory history = new TcProjectEquipmentHistory();
                 BeanUtils.copyBeanProp(history, machine);
@@ -961,7 +972,7 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
         // 同时变更区域,如果变更的目标用户有多个区域权限,取有关联的第一个
         TcProject projectDb = tcProjectMapper.selectTcProjectByProjectId(tcProject.getProjectId());
         List<Long> areaIdList = user.getAreaIdList();
-        if (CollectionUtils.isNotEmpty(areaIdList)) {
+        if (isNotEmpty(areaIdList)) {
             Long areaId = projectDb.getAreaId();
             List<TbArea> areas = tbAreaMapper.selectListByIdsAndAncestorId(areaIdList, areaId);
             // Map<Long, List<String>> area = areas.stream().collect(Collectors.toMap(TbArea::getAreaId, item -> Arrays.stream(item.getPermissionChar().split(",")).filter(StringUtils::isNotBlank).collect(Collectors.toList())));
@@ -985,7 +996,7 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
 
         List<TcProjectEquipment> machineList = tcProjectEquipmentService.list(Wrappers.<TcProjectEquipment>lambdaQuery()
                 .eq(TcProjectEquipment::getProjectId, exist.getProjectId()).eq(TcProjectEquipment::getDelFlag, DelFlagEnum.NORMAL.getValue()));
-        if (CollectionUtils.isNotEmpty(machineList)) {
+        if (isNotEmpty(machineList)) {
             List<TcProjectEquipmentHistory> equipmentHistories = machineList.stream().map(machine -> {
                 TcProjectEquipmentHistory history = new TcProjectEquipmentHistory();
                 BeanUtils.copyBeanProp(history, machine);
@@ -1509,22 +1520,102 @@ public class TcProjectServiceImpl extends ServiceImpl<TcProjectMapper, TcProject
     }
 
     @Override
-    public List<AgentTargetProgressVo> getAgentTargetProgressList(AgentCompleteOrder agentCompleteOrder) {
+    public List<Map<String, Object>> getAgentTargetProgressList(AgentCompleteOrder agentCompleteOrder) {
         if (StringUtils.isNotEmpty(agentCompleteOrder.getCity())) {
             agentCompleteOrder.setCity(agentCompleteOrder.getCity().replaceAll("%", "/%").replaceAll("_", "/_"));
         }
-        List<AgentTargetProgressVo> agentTargetProgressVoList = tcProjectMapper.getAgentTargetProgressList(agentCompleteOrder);
-        for (AgentTargetProgressVo agentTargetProgressVo : agentTargetProgressVoList) {
-            AgentTargetProgressVo agentCompleteOrder1 = new AgentTargetProgressVo();
-            agentCompleteOrder1.setAgentId(agentTargetProgressVo.getAgentId());
-            agentCompleteOrder1.setYearParam(agentCompleteOrder.getYearParam());
-            agentCompleteOrder1.setTargetElevatorCount(agentTargetProgressVo.getTargetElevatorCount());
-            List<AgentTargetProgressVo> listSub = tcProjectMapper.getAgentTargetProgressListSub(agentCompleteOrder1);
-            agentTargetProgressVo.setAgentTargetProgressVoList(listSub);
-        }
+        List<Map<String, Object>> agentTargetProgressVoList = tcProjectMapper.getAgentTargetProgressList(agentCompleteOrder);
+
+        // 获取区域名称
+        List<String> countryIds = Lists.newArrayList();
+        agentTargetProgressVoList.forEach(item -> {
+            countryIds.addAll(Arrays.stream(StringUtils.defaultIfBlank((String) item.get("countryId"), Constants.EMPTY).split(",")).collect(Collectors.toList()));
+        });
+        List<Long> ids = countryIds.stream().filter(StringUtils::isNotBlank).map(Long::valueOf).collect(Collectors.toList());
+        List<Long> areaIds = agentTargetProgressVoList.stream().map(item -> (Long)item.get("areaId")).collect(Collectors.toList());
+        Map<String, String> countryNameMap = isNotEmpty(ids) ? tbCountryService.listByIds(ids).stream().collect(Collectors.toMap(item -> item.getCountryId().toString(), LocalUtils.localCountryNameFun())): Maps.newHashMap();
+        Map<String, String> areaNameMap = isNotEmpty(areaIds) ? tbAreaMapper.selectAreaListByIds(areaIds).stream().collect(Collectors.toMap(item -> item.getAreaId().toString(), LocalUtils.localAreaNameFun())) : new HashMap<>();
+        agentTargetProgressVoList.forEach(item -> {
+            item.put("areaName", areaNameMap.get(item.get("areaId").toString()));
+            String countryId = StringUtils.defaultIfBlank((String) item.get("countryId"), Constants.EMPTY);
+            item.put("countryName", Arrays.stream(countryId.split(",")).filter(StringUtils::isNotBlank).map(countryNameMap::get).collect(Collectors.joining(",")));
+        });
+
         return agentTargetProgressVoList;
     }
 
+    @Override
+    public void exportCustomerCompleteOrder(AgentCompleteOrder agentCompleteOrder) {
+
+        List<List<String>> tableData = new ArrayList<>();
+        List<List<String>> header = Lists.newArrayList(
+                Lists.newArrayList("区域", "国家", "城市", "代理商名", "年销售目标台数", "代理商等级"),
+                Lists.newArrayList("", "", "", "", "", "")
+        );
+
+        // 周数据
+        List<Integer> weeks = isNotEmpty(agentCompleteOrder.getWeeks()) ?
+                agentCompleteOrder.getWeeks().stream().sorted().collect(Collectors.toList()) : new ArrayList<>();
+        List<Map<String, Object>> data = getAgentTargetProgressList(agentCompleteOrder);
+        weeks.forEach(week -> {
+            header.get(0).addAll(Lists.newArrayList(week.toString(), ""));
+            header.get(1).addAll(Lists.newArrayList("出货台数", "完成率"));
+        });
+        tableData.addAll(header);
+
+        data.forEach(item -> {
+            List<String> row = Lists.newArrayList(
+                    (String)item.get("areaName"),
+                    (String)item.get("countryName"),
+                    (String)item.get("city"),
+                    (String)item.get("agentName"),
+                    (String)item.get("agentName"),
+                    (String)item.get("agentLevel")
+            );
+            weeks.forEach(week -> {
+                row.add(item.get("count_" + week).toString());
+                row.add(item.get("percent_" + week).toString());
+            });
+            tableData.add(row);
+        });
+
+        if (!agentCompleteOrder.isShowColumn()){
+            tableData.forEach(row -> row.remove(0));
+        }
+
+        //表头单元格合并
+        WriteHandler mergeStrategy = new SheetWriteHandler() {
+            @Override
+            public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
+                List<String> weekInfo = weeks.stream().map(String::valueOf).collect(Collectors.toList());
+                for (int i = 0; i < tableData.get(0).size(); i++) {
+                    String val = tableData.get(0).get(i);
+                    if (StringUtils.isBlank(val)){
+                        continue;
+                    }
+                    CellRangeAddress cellRangeAddress;
+                    if (weekInfo.contains(val)){
+                        cellRangeAddress = new CellRangeAddress(0, 0, i, i + 1);
+                    } else {
+                        cellRangeAddress = new CellRangeAddress(0, 1, i, i);
+                    }
+                    writeSheetHolder.getSheet().addMergedRegionUnsafe(cellRangeAddress);
+                }
+            }
+        };
+
+        // 返回生成的excel文件
+        HttpServletResponse response = ServletUtils.getResponse();
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+        response.setCharacterEncoding("utf-8");
+        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).registerWriteHandler(mergeStrategy).build()) {
+            excelWriter.write(tableData, EasyExcel.writerSheet(agentCompleteOrder.getYearParam() + "代理商目标管理进度表").build());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new ServiceException("导出失败");
+        }
+    }
+
     private TcProject convert2Project(ProjectFromInfo helper) {
         TcProject project = new TcProject();
         project.setAccountId(helper.getAccountId());

+ 42 - 28
RuoYi-Vue-fast-master/src/main/resources/mybatis/business/TcProjectMapper.xml

@@ -1289,35 +1289,49 @@
         group by tcl.end_customers,tcl.area_id,tcl.country_id,tcl.city
     </select>
 
-    <select id="getAgentTargetProgressList" parameterType="com.ruoyi.project.business.domain.vo.board.AgentCompleteOrder"
-            resultType="com.ruoyi.project.business.domain.vo.board.AgentTargetProgressVo">
+    <select id="getAgentTargetProgressList" resultType="java.util.Map">
         select
-            tcl.agent_id as agentId,
-            tcl.area_id AS areaId,
-            tcl.country_id AS countryId,
-            tcl.city,
-            max( tba.area_name ) AS areaName,
-            max( c.country_name ) AS countryName,
-            sum(tat.target_elevator_count) as targetElevatorCount,
-            max(ta.agent_level) as agentLevel
-        from tq_contract_lift as tcl
-                 left join tb_agent_target as tat on tcl.agent_id = tat.agent_id and tat.del_flag = '0' and  DATE_FORMAT(tat.target_year, '%Y') = #{yearParam}
-                 left join tb_agent as ta on ta.agent_id = tcl.agent_id and ta.del_flag = '0'
-                 LEFT JOIN tb_area tba ON tcl.area_id = tba.area_id
-                 LEFT JOIN tb_country c ON tcl.country_id = c.country_id
-        where DATE_FORMAT(tcl.create_time, '%Y') = #{yearParam}
-        GROUP BY
-            tcl.agent_id,
-            tcl.area_id,
-            tcl.country_id,
-            tcl.city
-    </select>
-    <select id="getAgentTargetProgressListSub" parameterType="com.ruoyi.project.business.domain.vo.board.AgentTargetProgressVo"
-            resultType="com.ruoyi.project.business.domain.vo.board.AgentTargetProgressVo">
-        select sum(count) as shippedQty,(sum(count) / #{targetElevatorCount} * 100) as targetCompletionRate,'1' as week
+        a.agent_id as agentId,
+        a.agent_name as agentName,
+        a.area_id as areaId,
+        a.country_id as countryId,
+        a.city,
+        a.agent_level as agentLevel,
+        <if test="weeks != null and weeks.size() > 0">
+            <foreach collection="weeks" item="week">
+                sum(if(cl.delivery_week &lt;= #{week}, 1, 0)) as count_#{week},
+                ifnull(round(sum(if(cl.delivery_week &lt;= #{week}, 1, 0)) * 100 / t.target_elevator_count , 2), 0) as percent_#{week},
+            </foreach>
+        </if>
+        t.target_elevator_count as targetElevatorCount
+        from tb_agent a
+        left join tb_agent_target t on a.agent_id = t.agent_id and t.del_flag = 0 and YEAR(t.target_year) = #{yearParam}
+        left join
+        (
+        select agent_id, CEIL((dayofyear(actual_delivery_date) + dayofweek(DATE_FORMAT(actual_delivery_date, '%Y-01-01'))) / 7) as `delivery_week`
         from tq_contract_lift
-        where DATE_FORMAT(create_time, '%Y') = #{yearParam}
-          and agent_id = #{agentId}
-        group by WEEK(actual_delivery_date,6)
+        where del_flag = 0 and actual_delivery_date is not null and YEAR(actual_delivery_date) = #{yearParam}
+        ) cl on a.agent_id = cl.agent_id
+        where a.del_flag = 0 and t.target_id is not null
+        <if test="areaId != null and areaId.size() > 0">
+            and a.area_id in
+            <foreach collection="areaId" item="id" open="(" separator="," close=")">
+                #{id}
+            </foreach>
+        </if>
+        <if test="countryId != null and countryId.size() > 0">
+            and a.country_id in
+            <foreach collection="countryId" item="id" open="(" separator="," close=")">
+                #{id}
+            </foreach>
+        </if>
+        <if test="agentId != null and agentId.size() > 0">
+            and a.agent_id in
+            <foreach collection="agentId" item="id" open="(" separator="," close=")">
+                #{id}
+            </foreach>
+        </if>
+        <if test="city != null and city != ''">and a.city like concat ('%', #{city}, '%')</if>
+        group by a.agent_id
     </select>
 </mapper>

+ 58 - 42
ruoyi-ui-vue2/src/views/board/agentTargetProgress/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div v-loading="pageLoading" class="app-container">
+  <div class="app-container">
     <div style="padding-bottom: 10px;">
       <span style="padding-right: 20px;font-size: 16px;font-weight: bold;">{{ $t('agentProjectStatistics.year') }}</span>
       <el-date-picker
@@ -11,12 +11,12 @@
         :editable="false"
       >
       </el-date-picker>
-      <span style="margin-left:10px;padding-right: 20px;font-size: 16px;font-weight: bold;">{{ weekList }}{{ $t('周') }}</span>
-      <el-select   v-model="queryParams.weeks" multiple filterable >
+      <span style="margin-left:10px;padding-right: 20px;font-size: 16px;font-weight: bold;">{{ $t('周') }}</span>
+      <el-select   v-model="queryParams.weeks" multiple filterable clearable >
         <el-option v-for="item in weekList" :key="item" :label="item" :value="item"></el-option>
       </el-select>
-      <el-button style="margin-left: 10px;" type="primary" icon="el-icon-search" size="mini" @click="getList">{{ $t('common.search') }}
-      </el-button>
+      <el-button style="margin-left: 10px;" type="primary" icon="el-icon-search" size="mini" @click="getList">{{ $t('common.search') }}</el-button>
+      <el-button icon="el-icon-refresh" pageSize="small" size="small" @click="resetQuery">{{ $t('common.reset') }}</el-button>
     </div>
     <card-table :delProp="[]" :loading="loading" :modalData="list" :searchParams="queryParams"
                 :tableSearch="true" labelWidth="120px" @columnSearch="handleQuery" @pagination="getList" :max-height="$store.getters.tableMaxHeight"
@@ -32,12 +32,20 @@
 <!--        <Column :label="$t('project.area')" prop="areaName" show-search :searchParams="queryParams"/>-->
         <Column v-if="showAreaColumn" :label="$t('project.area')" prop="areaId" :searchParams="queryParams"
                 :searchDict="areaList" :showSearch="true" valueProp="first" labelProp="second"
-                searchType="select" selectMore />
+                searchType="select" selectMore>
+                <template #default="{ row }">
+                  <span>{{ row.areaName }}</span>
+                </template>
+        </Column>
         <!--国家-->
 <!--        <Column :label="$t('project.countryId')" prop="countryName" show-search :searchParams="queryParams"/>-->
         <Column :label="$t('account.country')" prop="countryId" :searchParams="queryParams" :showSearch="true"
                 valueProp="first" labelProp="second" searchType="select"
-                :searchDict="countryList" select-more />
+                :searchDict="countryList" select-more>
+          <template #default="{ row }">
+            <span>{{ row.countryName }}</span>
+          </template>
+        </Column>
         <!--城市-->
         <Column :label="$t('project.city')" prop="city" show-search :searchParams="queryParams"/>
         <!--代理商名-->
@@ -57,10 +65,9 @@
         <Column label="年度销售目标台数" prop="targetElevatorCount"  />
         <!--代理商等级-->
         <Column label="代理商等级" prop="agentLevel" searchType="select" :searchDict="dict.type.agent_level" />
-        <el-table-column v-for="week in data" :label="week">
-
-          <el-table-column label="出货台数" :prop="'shippedQty' + week"/>
-          <el-table-column label="目标完成率" :prop="'targetCompletionRate' + week"/>
+        <el-table-column v-for="week in tableWeeks" :label="String(week)">
+          <el-table-column label="出货台数" :prop="`count_${week}`" align="right"/>
+          <el-table-column label="完成率" :prop="`percent_${week}`" :formatter="(row, column, cellValue) => cellValue + '%'" align="right"/>
         </el-table-column>
       </template>
     </card-table>
@@ -93,15 +100,13 @@ export default {
         pageSize: 10,
         total: 0,
         language: this.$i18n.locale,
-        yearParam: moment().format('YYYY'),
+        yearParam: null,
         weeks: []
       },
       list:[],
       areaList: [],
       countryList: [],
-      agentList: [],
-      data:['1','2','3']
-
+      agentList: []
     }
   },
   computed:{
@@ -114,13 +119,35 @@ export default {
       return !this.$store.getters.roles.some(role => invisibleRoles.includes(role));
     },
     weekList(){
-      console.log(this.queryParams.yearParam, moment(this.queryParams.yearParam, 'YYYY').locale('en').isoWeeksInYear())
-      return moment(this.queryParams.yearParam, 'YYYY').locale('en').isoWeeksInYear();
+      const currentDate = moment(this.queryParams.yearParam, 'YYYY')
+      const dayOfYear = currentDate.endOf('year').dayOfYear()
+      const dayOfWeek = currentDate.month(0).date(1).day()
+      return Math.ceil((dayOfYear + dayOfWeek) / 7)
+    },
+    tableWeeks(){
+      if(!this.list || this.list.length === 0){
+        return this.queryParams.yearParam || []
+      }
+      const result = [];
+      this.list.forEach(item => {
+        Object.keys(item).forEach(key => {
+          if (key.startsWith('count_')) {
+            const week = Number(key.replace('count_', ''))
+            if (!result.includes(week)){
+              result.push(week)
+            }
+          }
+        })
+      })
+      return result.sort((a, b) => a - b);
     }
   },
   created() {
-    this.handleQuery()
-    this.getAgentList();
+    this.getAgentList()
+    this.getAreaList()
+    this.getNationList()
+
+    this.resetQuery()
   },
   methods:{
     /** 导出按钮操作 */
@@ -135,7 +162,6 @@ export default {
       const yearString = `${year}`;
       this.queryParams.yearParam = yearString;
       this.handleQuery()
-      this.getAgentList()
     },
     /** 搜索按钮操作 */
     handleQuery() {
@@ -143,26 +169,14 @@ export default {
       this.getList();
     },
     /** 查询列表数据 */
-    async getList() {
+    getList() {
       this.loading = true;
-      await getAgentTargetProgressList(this.queryParams).then(response => {
+      getAgentTargetProgressList(this.queryParams).then(response => {
         this.list = response.rows;
-        this.list.forEach(item => {
-          for (let week of this.data){
-            let weekData =   item.agentTargetProgressVoList.filter(it => it.week === week)[0]
-            if(weekData){
-              item['shippedQty' + week] = weekData.shippedQty
-              item['targetCompletionRate' + week] = weekData.targetCompletionRate
-            }
-          }
-        })
         this.queryParams.total = response.total;
-        this.loading = false;
       }).finally(() => {
         this.loading = false;
       })
-      this.getAreaList();
-      this.getNationList();
     },
     getAreaList() {
       getAreaList().then(res => {
@@ -177,19 +191,21 @@ export default {
     },
     getAgentList() {
       selectForYear(null).then(res => {
-        this.agentList = res.data;
-        if (this.userInfo.deptId == 0) {
-          this.agentList.unshift({agentId: 0, agentName: this.$t('common.head')});
-        }
+        this.agentList = res.data.filter(item => item.agentId !== 0)
       })
     },
     /** 重置按钮操作 */
     resetQuery() {
-      this.$set(this.queryParams, 'agentNo', null);
-      this.$set(this.queryParams, 'agentName', null);
+      const currentDate = moment().locale('en')
+      const weekNumber = currentDate.week();
+      this.queryParams.weeks = weekNumber > 1 ? [weekNumber - 1, weekNumber] : [weekNumber];
+      this.$set(this.queryParams, 'yearParam', moment().format('YYYY'));
+      this.$set(this.queryParams, 'city', null);
       this.$set(this.queryParams, 'areaId', null);
-      this.$set(this.queryParams, 'agentType', null);
-      this.$set(this.queryParams, 'agentLevel', null);
+      this.$set(this.queryParams, 'countryId', null);
+      this.$set(this.queryParams, 'agentId', null);
+      this.$set(this.queryParams, 'pageNum', 1);
+      this.$set(this.queryParams, 'pageSize', 10);
       this.handleQuery();
     },
   },

+ 10 - 6
ruoyi-ui-vue2/src/views/board/contractSigningStatistic/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div v-loading="loading" class="app-container">
+  <div class="app-container">
     <div style="padding-bottom: 10px;">
       <span style="padding-right: 20px;font-size: 16px;font-weight: bold;">{{ $t('周') }}</span>
       <el-date-picker
@@ -11,8 +11,8 @@
         placeholder="选择周"
         @change="handleWeekChange"
         :clearable="false"/>
-      <el-button style="margin-left: 10px;" type="primary" icon="el-icon-search" size="mini" @click="getList">{{ $t('common.search') }}
-      </el-button>
+      <el-button style="margin-left: 10px;" type="primary" icon="el-icon-search" size="mini" @click="getList">{{ $t('common.search') }}</el-button>
+      <el-button icon="el-icon-refresh" pageSize="small" size="small" @click="resetQuery">{{ $t('common.reset') }}</el-button>
     </div>
 
     <div class="card-Table">
@@ -114,8 +114,7 @@ export default {
     }
   },
   created() {
-    this.handleWeekChange(moment().startOf('week').format('YYYY-MM-DD'))
-    this.getList()
+    this.resetQuery()
   },
   computed: {
     weekValue(){
@@ -175,7 +174,12 @@ export default {
         return []
       }
       return list[list.length - 1] || []
-    }
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.handleWeekChange(moment().startOf('week').format('YYYY-MM-DD'))
+      this.getList();
+    },
   },
 }
 </script>