qin hai 1 ano
pai
achega
a507fc39cc

+ 40 - 0
src/main/java/com/poteviohealth/cgp/statistics/controller/OrderController.java

@@ -12,13 +12,16 @@ import com.poteviohealth.cgp.common.filter.TokenContext;
 import com.poteviohealth.cgp.common.filter.repeatSubmit.RepeatSubmit;
 import com.poteviohealth.cgp.common.utils.ExcelUtils;
 import com.poteviohealth.cgp.statistics.model.indto.DishesOrderWebInDTO;
+import com.poteviohealth.cgp.statistics.model.indto.OrderCostWebInDTO;
 import com.poteviohealth.cgp.statistics.model.indto.OrderServiceWebInDTO;
 import com.poteviohealth.cgp.statistics.model.outdto.DishesOrderWebOutDTO;
+import com.poteviohealth.cgp.statistics.model.outdto.OrderCostWebOutDTO;
 import com.poteviohealth.cgp.statistics.model.outdto.OrderExcelDTO;
 import com.poteviohealth.cgp.statistics.service.IOrderService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.time.DateFormatUtils;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -27,6 +30,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 服务工单  前端控制器
@@ -92,8 +96,44 @@ public class OrderController extends BaseWebController {
                 }
             }
         }
+    }
 
+    @PostMapping(value = "/revenueExport")
+    @ApiOperation(httpMethod = "POST", value = "成本核算Excel导出")
+    @RepeatSubmit
+    @MethodTime
+    public void revenueExport(HttpServletResponse resp, @RequestBody OrderCostWebInDTO orderCostWebInDTO){
+        String key ="revenueExport";
+        String error =  this.checkExcelExport(key);
+        try{
+            if ("".equals(error)) {
+                String templateLocation = "classpath:excel/revenue.xlsx";
+                String filename = "";
+                Map<String, Object> data = Maps.newHashMap();
+                String dateStr = "工单成本核算";
+                if(orderCostWebInDTO.getStartDate() != null){
+                    dateStr = DateFormatUtils.format(orderCostWebInDTO.getStartDate(),"yyyy-MM-dd")+"~"+
+                            DateFormatUtils.format(orderCostWebInDTO.getEndDate(),"yyyy-MM-dd")+dateStr;
+                }
 
+                List<OrderCostWebOutDTO> list = orderService.OrderCostList(orderCostWebInDTO);
+                double totalActualCost = list.stream().mapToDouble(a-> Double.parseDouble(a.getStandard())).sum();
+                double totalActualIncome =list.stream().mapToDouble(a-> Double.parseDouble(a.getActual())).sum();
+                data.put("title",dateStr);
+                data.put("title2","标准成本合计:"+totalActualCost+"元;成本金额合计:"+totalActualIncome+"元");
+                ExcelUtils.easyDownload(templateLocation,data , list, filename, resp);
+            }else{
+                throw new BusinessException(error);
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }finally {
+            if(cacheService.exists(key)){
+                if(cacheService.get(key).equals(TokenContext.cureWebUser().getUserId().toString())){
+                    cacheService.del(key);
+                }
+            }
+        }
     }
 
     @DistributedLock(fairLock =true)

+ 13 - 0
src/main/java/com/poteviohealth/cgp/statistics/mapper/OrderMapper.java

@@ -192,4 +192,17 @@ public interface OrderMapper extends BaseMapper<Order>{
     @SqlParser(filter=true)
     List<DishesOrderWebOutDTO> dishesOrderExcel(@Param(Constants.WRAPPER) Wrapper wrapper,@Param("dbName")String dbName,@Param("operatorId")Integer operatorId,@Param("start")Integer start,@Param("end")Integer end);
 
+
+    @SqlParser(filter = true)
+    int costOrderPageListAllSize(@Param(Constants.WRAPPER) Wrapper wrapper,@Param("dbName")String dbName,@Param("operatorId")Integer operatorId);
+
+
+    /**
+     * excel
+     * @param wrapper
+     * @return
+     */
+    @SqlParser(filter=true)
+    List<OrderCostWebOutDTO> costOrderExcel(@Param(Constants.WRAPPER) Wrapper wrapper,@Param("dbName")String dbName,@Param("operatorId")Integer operatorId,@Param("start")Integer start,@Param("end")Integer end);
+
 }

+ 63 - 0
src/main/java/com/poteviohealth/cgp/statistics/model/indto/OrderCostWebInDTO.java

@@ -0,0 +1,63 @@
+package com.poteviohealth.cgp.statistics.model.indto;
+
+import com.poteviohealth.cgp.common.model.OrgPageQuery;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 成本列表查询
+ * @author Qin
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="成本列表查询")
+public class OrderCostWebInDTO extends OrgPageQuery {
+
+    @ApiModelProperty(value="搜索订单code")
+    private String code;
+
+    @ApiModelProperty(value="服务人员Id")
+    private Integer employeeId;
+
+    @ApiModelProperty(value = "调整状态:1:未调整;2:已调整")
+    private Integer costStatus;
+
+    @ApiModelProperty(value = "核算状态:1:未核算;2:已核算")
+    private Integer revenueStatus;
+
+    @ApiModelProperty(value = "起始时间")
+    private Date startDate;
+
+    @ApiModelProperty(value = "结束时间")
+    private Date endDate;
+
+    @ApiModelProperty(value = "服务方")
+    private List<Integer> serviceStationIds;
+
+    @ApiModelProperty(value = "服务人员")
+    private List<Integer> employees;
+
+    @ApiModelProperty(value = "是否选择0:未选择;1:选择")
+    private Integer selected;
+
+    @ApiModelProperty(value = "id集合")
+    private List<Long> ids;
+
+    @ApiModelProperty(value = "核算Id")
+    private Long id;
+
+    @ApiModelProperty(value = "筛选时间")
+    private String searchDateStr;
+
+    @ApiModelProperty(value = "合同年份")
+    private String costYear;
+}

+ 139 - 0
src/main/java/com/poteviohealth/cgp/statistics/model/outdto/OrderCostWebOutDTO.java

@@ -0,0 +1,139 @@
+package com.poteviohealth.cgp.statistics.model.outdto;
+
+import com.poteviohealth.cgp.order.mapstruct.transform.DateTransfrom;
+import com.poteviohealth.cgp.order.mapstruct.transform.LongTransfrom;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.mapstruct.Mapper;
+
+import java.util.Date;
+
+/**
+ * @Author QIN
+ * @Date 2019/7/16 19:08
+ * @Param 订单DTO
+ * @return
+**/
+@Data
+@ApiModel(value="成本调整查询出参")
+@Mapper(uses = {LongTransfrom.class, DateTransfrom.class})
+public class OrderCostWebOutDTO {
+
+    @ApiModelProperty(value="id")
+    private Long orderCostId;
+
+    @ApiModelProperty(value = "订单逻辑主键id")
+    private Long orderId;
+
+    @ApiModelProperty(value = "订单号")
+    private String sn;
+
+    @ApiModelProperty(value = "服务人员Id")
+    private Integer employeeId;
+
+    @ApiModelProperty(value = "服务人员名称")
+    private String employeeName;
+
+    @ApiModelProperty(value = "服务方Id")
+    private Integer serviceStationId;
+
+    @ApiModelProperty(value = "服务驿站名称")
+    private String serviceStationName;
+
+    @ApiModelProperty(value = "归属驿站Id")
+    private Integer stationId;
+
+    @ApiModelProperty(value = "归属驿站")
+    private String stationName;
+
+    @ApiModelProperty(value = "单价")
+    private String signPrice;
+
+    @ApiModelProperty(value = "数量")
+    private Integer num;
+
+    @ApiModelProperty(value = "金额")
+    private String price;
+
+    @ApiModelProperty(value = "人工成本")
+    private String labor;
+
+    @ApiModelProperty(value = "标准成本")
+    private String standard;
+
+    @ApiModelProperty(value = "成本调整")
+    private String adjustment;
+
+    @ApiModelProperty(value = "实际成本")
+    private String actual;
+
+    @ApiModelProperty(value = "收入调整")
+    private String income;
+
+    @ApiModelProperty(value = "实际金额")
+    private String money;
+
+    @ApiModelProperty(value = "核算日期")
+    private Date revenueDate;
+
+    @ApiModelProperty(value = "核算人")
+    private String revenueUser;
+
+    @ApiModelProperty(value = "调整状态:1:未调整;2:已调整")
+    private Integer costStatus;
+
+    @ApiModelProperty(value = "调整状态:1:未调整;2:已调整")
+    private String costStatusStr;
+
+    @ApiModelProperty(value = "核算状态:1:未核算;2:已核算")
+    private Integer revenueStatus;
+
+    @ApiModelProperty(value = "核算状态:1:未核算;2:已核算")
+    private String revenueStatusStr;
+
+    @ApiModelProperty(value = "最终调整原因")
+    private String remark;
+
+    @ApiModelProperty(value="结算归属")
+    private String settlementAttribution;
+
+    @ApiModelProperty(value = "下单时间")
+    private Date orderTime;
+
+    @ApiModelProperty(value = "工单结束时间")
+    private Date endTime;
+
+    @ApiModelProperty(value = "完成时间")
+    private Date finishTime;
+
+    @ApiModelProperty(value = "类型名称")
+    private String categoryName;
+
+    @ApiModelProperty(value = "客户姓名")
+    private String customerName;
+
+    @ApiModelProperty(value = "客户类型")
+    private String customerType;
+
+    @ApiModelProperty(value = "收货地址")
+    private String address;
+
+    @ApiModelProperty(value = "区域名称", name = "countryName")
+    private String countryName;
+
+    @ApiModelProperty(value = "服务名称")
+    private String serviceName;
+
+    @ApiModelProperty(value = "支付金额")
+    private String payPrice;
+
+    @ApiModelProperty(value = "支付流水号")
+    private String transactionId;
+
+    @ApiModelProperty(value = "合同年份")
+    private String costYear;
+
+    @ApiModelProperty(value = "工时")
+    private String manHour;
+}

+ 4 - 0
src/main/java/com/poteviohealth/cgp/statistics/service/IOrderService.java

@@ -3,8 +3,10 @@ package com.poteviohealth.cgp.statistics.service;
 import com.poteviohealth.cgp.common.service.IBaseService;
 import com.poteviohealth.cgp.statistics.model.Order;
 import com.poteviohealth.cgp.statistics.model.indto.DishesOrderWebInDTO;
+import com.poteviohealth.cgp.statistics.model.indto.OrderCostWebInDTO;
 import com.poteviohealth.cgp.statistics.model.indto.OrderServiceWebInDTO;
 import com.poteviohealth.cgp.statistics.model.outdto.DishesOrderWebOutDTO;
+import com.poteviohealth.cgp.statistics.model.outdto.OrderCostWebOutDTO;
 import com.poteviohealth.cgp.statistics.model.outdto.OrderExcelDTO;
 
 import java.util.List;
@@ -34,4 +36,6 @@ public interface IOrderService extends IBaseService<Order> {
      */
     List<DishesOrderWebOutDTO> orderDishes(DishesOrderWebInDTO dto);
 
+    List<OrderCostWebOutDTO> OrderCostList(OrderCostWebInDTO orderCostWebInDTO);
+
 }

+ 67 - 0
src/main/java/com/poteviohealth/cgp/statistics/service/impl/OrderServiceImpl.java

@@ -24,9 +24,11 @@ import com.poteviohealth.cgp.common.service.impl.BaseServiceImpl;
 import com.poteviohealth.cgp.statistics.mapper.OrderMapper;
 import com.poteviohealth.cgp.statistics.model.Order;
 import com.poteviohealth.cgp.statistics.model.indto.DishesOrderWebInDTO;
+import com.poteviohealth.cgp.statistics.model.indto.OrderCostWebInDTO;
 import com.poteviohealth.cgp.statistics.model.indto.OrderServiceWebInDTO;
 import com.poteviohealth.cgp.statistics.model.outdto.*;
 import com.poteviohealth.cgp.statistics.service.IOrderService;
+import com.poteviohealth.cgp.statistics.utils.CostOrderExcelTask;
 import com.poteviohealth.cgp.statistics.utils.DishesOrderExcelTask;
 import com.poteviohealth.cgp.statistics.utils.OrderExcelTask;
 import lombok.extern.log4j.Log4j2;
@@ -232,6 +234,71 @@ public class OrderServiceImpl extends BaseServiceImpl<OrderMapper, Order> implem
         return list;
     }
 
+    @Override
+    public List<OrderCostWebOutDTO> OrderCostList(OrderCostWebInDTO orderCostWebInDTO) {
+        Integer operatorId = TokenContext.cureOperatorId();
+        QueryWrapper queryWrapper = webCostQuery(orderCostWebInDTO);
+        int count = baseMapper.costOrderPageListAllSize(queryWrapper,dbName,operatorId);
+        //每页1000条,计算总页数
+        int maxPage = (int) Math.ceil(count/10000.0);
+        List<OrderCostWebOutDTO> list = Lists.newArrayList();
+        ForkJoinPool pool = new ForkJoinPool();
+        try {
+            CostOrderExcelTask task = new CostOrderExcelTask(1,maxPage, queryWrapper, operatorId, dbName,baseMapper);
+            Future<List<OrderCostWebOutDTO>> future = pool.submit(task);
+            do {
+                pool.awaitTermination(1, TimeUnit.SECONDS);
+            } while (!future.isDone());
+            pool.shutdown();
+            list = future.get();
+        }catch (Exception e){
+            e.printStackTrace();
+            throw new BuilderException("成本核算导出失败,请重新操作");
+        }
+        return list;
+    }
+
+    private QueryWrapper webCostQuery(OrderCostWebInDTO orderWebInDTO) {
+        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
+        String searchTime = "o.order_time";
+        if(StringUtils.isNotBlank(orderWebInDTO.getSearchDateStr())){
+            searchTime = orderWebInDTO.getSearchDateStr();
+        }
+        if (orderWebInDTO.getStartDate() != null) {
+            orderQueryWrapper.ge("o."+searchTime, orderWebInDTO.getStartDate());
+        }
+        if (orderWebInDTO.getEndDate() != null) {
+            orderQueryWrapper.le( "o."+searchTime, orderWebInDTO.getEndDate());
+        }
+        orderQueryWrapper.in( !orderWebInDTO.getSupplierIds().isEmpty(),"o.supplier_id", orderWebInDTO.getSupplierIds());
+        if(orderWebInDTO.getStationIds() != null && !orderWebInDTO.getStationIds().isEmpty()){
+            orderQueryWrapper.in( "o.station_id", orderWebInDTO.getStationIds());
+        }
+
+        if(orderWebInDTO.getServiceStationIds() != null && !orderWebInDTO.getServiceStationIds().isEmpty()){
+            orderQueryWrapper.in( "o.service_station_id", orderWebInDTO.getServiceStationIds());
+        }
+
+        if(orderWebInDTO.getEmployeeId() != null){
+            orderQueryWrapper.eq( "o.employee_id", orderWebInDTO.getEmployeeId());
+        }
+
+        if(StringUtils.isNotBlank(orderWebInDTO.getCode())){
+            orderQueryWrapper.eq( "so.n", orderWebInDTO.getCode());
+        }
+        orderQueryWrapper.eq( "o.status", 1);
+        if(orderWebInDTO.getRevenueStatus() != null){
+            orderQueryWrapper.eq( "o.revenue_status",orderWebInDTO.getRevenueStatus());
+        }
+        if(orderWebInDTO.getCostStatus() != null){
+            orderQueryWrapper.eq( "o.cost_status",orderWebInDTO.getCostStatus());
+        }
+        orderQueryWrapper.orderByDesc("o.order_cost_id");
+
+        return orderQueryWrapper;
+    }
+
+
     private QueryWrapper webQuery(DishesOrderWebInDTO orderWebInDTO) {
         QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
         if (StringUtils.isNotBlank(orderWebInDTO.getSn())) {

+ 72 - 0
src/main/java/com/poteviohealth/cgp/statistics/utils/CostOrderExcelTask.java

@@ -0,0 +1,72 @@
+package com.poteviohealth.cgp.statistics.utils;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.common.collect.Lists;
+import com.poteviohealth.cgp.statistics.mapper.OrderMapper;
+import com.poteviohealth.cgp.statistics.model.outdto.OrderCostWebOutDTO;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.RecursiveTask;
+
+/**
+ * @author Qin
+ */
+@Data
+public class CostOrderExcelTask extends RecursiveTask<List<OrderCostWebOutDTO>> {
+
+    private static final int MAX = 10000;
+    private int start;
+    private int end;
+    private QueryWrapper queryWrapper;
+    private Integer operatorId;
+    private String dbName;
+    private OrderMapper orderMapper;
+    public CostOrderExcelTask(int start, int end, QueryWrapper queryWrapper, Integer operatorId, String dbName, OrderMapper orderMapper){
+        super();
+        this.end = end;
+        this.start =start;
+        this.queryWrapper = queryWrapper;
+        this.operatorId = operatorId;
+        this.dbName = dbName;
+        this.orderMapper = orderMapper;
+    }
+
+     @Override
+    protected List<OrderCostWebOutDTO> compute() {
+        // 当end-start的值小于MAX时候,开始打印
+         List<OrderCostWebOutDTO> list = Lists.newArrayList();
+
+         int page = (end - start);
+        if (page < 2) {
+            // 小于最大值 直接执行
+                list.addAll(orderMapper.costOrderExcel(queryWrapper,dbName,operatorId,(start-1)*MAX,MAX));
+                if(page == 1){
+                    list.addAll(orderMapper.costOrderExcel(queryWrapper,dbName,operatorId,(end-1)*MAX,MAX));
+                }
+            return list;
+        } else {
+            // 将任务分解
+            List<CostOrderExcelTask> tasks = new ArrayList<>();
+            int middle =(start + end) / 2;
+            CostOrderExcelTask left = new CostOrderExcelTask(start,middle, queryWrapper,operatorId,dbName,orderMapper);
+            CostOrderExcelTask right = new CostOrderExcelTask(middle+1,end, queryWrapper,operatorId,dbName,orderMapper);
+            // 并行执行
+            invokeAll(left, right);
+            tasks.add(left);
+            tasks.add(right);
+            addResultFromTasks(list, tasks);
+            return list;
+        }
+    }
+
+    // 等待所有的任务运行结束
+    private void addResultFromTasks(List<OrderCostWebOutDTO> list, List<CostOrderExcelTask> tasks) {
+        for (CostOrderExcelTask item : tasks) {
+            if (item.join() != null) {
+                list.addAll(item.join());
+            }
+        }
+    }
+}

BIN=BIN
src/main/resources/excel/revenue.xlsx


+ 44 - 0
src/main/resources/mapper/statistics/OrderMapper.xml

@@ -306,4 +306,48 @@
           and ${ew.sqlSegment}
             limit #{start},#{end}
     </select>
+    <select id="costOrderPageListAllSize" resultType="java.lang.Integer">
+        SELECT count(*)
+        FROM
+            ${dbName}_order.o_order_cost_${operatorId} o
+        WHERE o.yn = 0
+          and ${ew.sqlSegment}
+    </select>
+    <select id="costOrderExcel" resultType="com.poteviohealth.cgp.statistics.model.outdto.OrderCostWebOutDTO">
+        SELECT
+            o.sn,
+            o.category_name,
+            o.cost_year,
+            o.customer_name,
+            o.customer_type,
+            o.station_name,
+            o.settlement_attribution,
+            o.service_station_name,
+            o.country_name,
+            o.address,
+            o.employee_name,
+            o.service_name,
+            DATE_FORMAT(o.order_time,'%Y-%m-%d %H:%i') AS orderTime,
+            DATE_FORMAT(o.end_time,'%Y-%m-%d %H:%i') AS end_time,
+            case when o.revenue_status = 1 then '未核算' else '已核算' end  as revenueStatusStr,
+            TRUNCATE (o.sign_price/ 100.0, 2 ) AS signPrice,
+            o.man_hour,
+            o.num,
+            TRUNCATE (o.price/ 100.0, 2 ) AS price,
+            TRUNCATE (o.labor/ 100.0, 2 ) as labor,
+            TRUNCATE (o.standard/ 100.0, 2 ) as standard,
+            TRUNCATE (o.adjustment/ 100.0, 2 ) as adjustment,
+            TRUNCATE (o.actual/ 100.0, 2 ) as actual,
+            TRUNCATE (o.income/ 100.0, 2 ) as income,
+            TRUNCATE (o.money/ 100.0, 2 ) as money,
+            DATE_FORMAT(o.revenue_date,'%Y-%m-%d %H:%i') AS revenueDate,
+            o.remark,
+            o.transaction_id,
+            TRUNCATE (o.pay_price/ 100.0, 2 ) as payPrice
+        FROM
+            ${dbName}_order.o_order_cost_${operatorId} o
+        WHERE o.yn = 0
+          and ${ew.sqlSegment}
+            limit #{start},#{end}
+    </select>
 </mapper>