Przeglądaj źródła

营业报表功能开发

huzhe 1 rok temu
rodzic
commit
dd4318865b

+ 26 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/DateUtils.java

@@ -165,4 +165,30 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
         ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
         return Date.from(zdt.toInstant());
     }
+
+    /**
+     * 获取年份第一天
+     * @param year
+     * @return
+     */
+    public static LocalDate firstDayOfYear(int year) {
+        return LocalDate.ofYearDay(year, 1);
+    }
+
+    /**
+     * 获取年份最后一天
+     * @param year
+     * @return
+     */
+    public static LocalDate lastDayOfYear(int year) {
+        return firstDayOfYear(year).plusYears(1).minusDays(1);
+    }
+
+    public static LocalDate firstDayOfMonth(int year, int month) {
+        return LocalDate.of(year, month, 1);
+    }
+
+    public static LocalDate lastDayOfMonth(int year, int month) {
+        return firstDayOfMonth(year, month).plusMonths(1).minusDays(1);
+    }
 }

+ 31 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/controller/XfConsumeDetailController.java

@@ -1,12 +1,14 @@
 package org.dromara.backstage.consumption.controller;
 
 import java.util.List;
+import java.util.Map;
 
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import org.dromara.backstage.consumption.domain.bo.XfConsumeDetailBo;
+import org.dromara.backstage.consumption.domain.vo.XfConsumeAnalyzeVo;
 import org.dromara.backstage.consumption.domain.vo.XfConsumeDetailVo;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
@@ -103,4 +105,33 @@ public class XfConsumeDetailController extends BaseController {
                           @PathVariable String[] consumeIds) {
         return toAjax(xfConsumeDetailService.deleteWithValidByIds(List.of(consumeIds), true));
     }
+
+    /**
+     *
+     * @param pageQuery 分页参数
+     * @param dateFormat 日期格式、分组统计条件
+     * @param groupByTerm 是否按机器统计
+     * @param accountIds 结算账户
+     * @param roomIds 所属区域、房间
+     * @param beginDate 开始日期
+     * @param endDate 结束日期
+     * @return
+     */
+    @GetMapping("/consumeAnalyze")
+    public TableDataInfo<XfConsumeAnalyzeVo> consumeAnalyze(PageQuery pageQuery,String dateFormat, boolean groupByTerm,
+                                                            String accountIds,String roomIds,String beginDate, String endDate) {
+        return xfConsumeDetailService.consumeAnalyze(pageQuery,dateFormat, groupByTerm, accountIds, roomIds, beginDate, endDate);
+    }
+
+
+    @Log(title = "营业报表导出", businessType = BusinessType.EXPORT)
+    @PostMapping("/exportConsumeAnalyze")
+    public void exportConsumeAnalyze(PageQuery pageQuery, String dateFormat, boolean groupByTerm,String accountIds
+            ,String roomIds,String beginDate, String endDate, HttpServletResponse response) {
+        pageQuery.setPageSize(100000);
+        List<XfConsumeAnalyzeVo> list = xfConsumeDetailService.consumeAnalyze(pageQuery,dateFormat, groupByTerm, accountIds, roomIds
+            , beginDate,
+            endDate).getRows();
+        ExcelUtil.exportExcel(list, "营业报表", XfConsumeAnalyzeVo.class, response);
+    }
 }

+ 75 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/domain/vo/XfConsumeAnalyzeVo.java

@@ -0,0 +1,75 @@
+package org.dromara.backstage.consumption.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.backstage.consumption.domain.XfConsumeDetail;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+
+/**
+ * 消费明细视图对象 t_xf_consumeDetail
+ *
+ * @author LionLi
+ * @date 2024-08-15
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class XfConsumeAnalyzeVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    @ExcelProperty(value = "结算账户")
+    private String accountName;
+
+    @ExcelProperty(value = "消费机")
+    private String termName;
+
+    @ExcelProperty(value = "消费时间")
+    private String consumeDate;
+
+    @ExcelProperty(value = "早餐金额")
+    private String zaoCanJinE;
+
+    @ExcelProperty(value = "早餐次数")
+    private String zaoCanCiShu;
+
+    @ExcelProperty(value = "午餐金额")
+    private String wuCanJinE;
+
+    @ExcelProperty(value = "午餐次数")
+    private String wuCanCiShu;
+
+    @ExcelProperty(value = "晚餐金额")
+    private String wanCanJinE;
+
+    @ExcelProperty(value = "晚餐次数")
+    private String wanCanCiShu;
+
+    @ExcelProperty(value = "宵夜金额")
+    private String xiaoYeJinE;
+
+    @ExcelProperty(value = "宵夜次数")
+    private String xiaoYeCiShu;
+
+    @ExcelProperty(value = "错扣补款金额")
+    private String tuiKuanJinE;
+
+    @ExcelProperty(value = "错扣补款次数")
+    private String tuiKuanCiShu;
+
+    @ExcelProperty(value = "小计金额")
+    private String xiaoJiJinE;
+
+    @ExcelProperty(value = "小计次数")
+    private String xiaoJiCiShu;
+
+}

+ 17 - 1
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/mapper/XfConsumeDetailMapper.java

@@ -1,8 +1,18 @@
 package org.dromara.backstage.consumption.mapper;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.MapKey;
+import org.apache.ibatis.annotations.Param;
 import org.dromara.backstage.consumption.domain.XfConsumeDetail;
+import org.dromara.backstage.consumption.domain.bo.XfConsumeDetailBo;
+import org.dromara.backstage.consumption.domain.vo.XfConsumeAnalyzeVo;
 import org.dromara.backstage.consumption.domain.vo.XfConsumeDetailVo;
+import org.dromara.backstage.payment.domain.PtUserAccount;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * 消费明细Mapper接口
@@ -11,5 +21,11 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
  * @date 2024-08-15
  */
 public interface XfConsumeDetailMapper extends BaseMapperPlus<XfConsumeDetail, XfConsumeDetailVo> {
-
+    @MapKey("accountName")
+    Page<XfConsumeAnalyzeVo> consumeAnalyze(Page<XfConsumeAnalyzeVo> page ,
+                                                 @Param("dateFormat") String dateFormat,
+                                               @Param("groupByTerm") boolean groupByTerm,
+                                                 @Param("accountIds") String accountIds, @Param("roomIds") String roomIds,
+                                                 @Param("beginDate") String beginDate, @Param(
+                                                      "endDate") String endDate);
 }

+ 20 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/IXfConsumeDetailService.java

@@ -1,12 +1,14 @@
 package org.dromara.backstage.consumption.service;
 
 import org.dromara.backstage.consumption.domain.bo.XfConsumeDetailBo;
+import org.dromara.backstage.consumption.domain.vo.XfConsumeAnalyzeVo;
 import org.dromara.backstage.consumption.domain.vo.XfConsumeDetailVo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 消费明细Service接口
@@ -81,4 +83,22 @@ public interface IXfConsumeDetailService {
      * @return 是否修改成功
      */
     Boolean updateByBoId(XfConsumeDetailBo bo);
+
+
+    /**
+     * 月度消费分析
+     * @param pageQuery
+     * @param dateFormat
+     * @param groupByTerm
+     * @param accountIds
+     * @param roomIds
+     * @param consumeDateBegin
+     * @param consumeDateEnd
+     * @return
+     */
+    TableDataInfo<XfConsumeAnalyzeVo> consumeAnalyze(PageQuery pageQuery,String dateFormat, boolean groupByTerm,
+                                                          String accountIds,
+                                                 String roomIds,
+                                                 String consumeDateBegin, String consumeDateEnd);
+
 }

+ 47 - 6
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/consumption/service/impl/XfConsumeDetailServiceImpl.java

@@ -1,25 +1,25 @@
 package org.dromara.backstage.consumption.service.impl;
 
-import com.baomidou.dynamic.datasource.annotation.DS;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
 import org.dromara.backstage.consumption.domain.XfConsumeDetail;
-import org.dromara.backstage.consumption.domain.XfCreditAccount;
-import org.dromara.backstage.consumption.domain.XfTerm;
 import org.dromara.backstage.consumption.domain.bo.XfConsumeDetailBo;
+import org.dromara.backstage.consumption.domain.vo.XfConsumeAnalyzeVo;
 import org.dromara.backstage.consumption.domain.vo.XfConsumeDetailVo;
 import org.dromara.backstage.consumption.mapper.XfConsumeDetailMapper;
 import org.dromara.backstage.consumption.service.IXfConsumeDetailService;
+import org.dromara.common.core.utils.DateUtils;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.springframework.stereotype.Service;
 
+import java.time.YearMonth;
+import java.time.format.DateTimeFormatter;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -58,8 +58,11 @@ public class XfConsumeDetailServiceImpl implements IXfConsumeDetailService {
     public TableDataInfo<XfConsumeDetailVo> queryPageList(XfConsumeDetailBo bo, PageQuery pageQuery) {
         LambdaQueryWrapper<XfConsumeDetail> lqw = buildQueryWrapper(bo);
         Map<String, Object> params = bo.getParams();
-        lqw.between(params.get("beginConsumeDate") != null && params.get("endConsumeDate") != null,
-            XfConsumeDetail::getConsumeDate, params.get("beginConsumeDate"), params.get("endConsumeDate"));
+        Object beginDate =  params.get("beginConsumeDate");
+        Object endDate =  params.get("endConsumeDate");
+        if(beginDate != null && endDate != null){
+            lqw.between(XfConsumeDetail::getConsumeDate, beginDate + " 00:00:00", endDate + " 23:59:59");
+        }
         lqw.orderByDesc(XfConsumeDetail::getConsumeDate);
         Page<XfConsumeDetailVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
         return TableDataInfo.build(result);
@@ -203,4 +206,42 @@ public class XfConsumeDetailServiceImpl implements IXfConsumeDetailService {
         updateWrapper.eq(XfConsumeDetail::getConsumeId, bo.getConsumeId());
         return baseMapper.update(null, updateWrapper)>0;
     }
+
+
+    @Override
+    public TableDataInfo<XfConsumeAnalyzeVo> consumeAnalyze(PageQuery pageQuery,String dateFormat, boolean groupByTerm,
+                                                            String accountIds,
+                                                        String roomIds, String beginDate, String endDate) {
+
+        if(StringUtils.isNotBlank(beginDate)){
+            if("yyyy".equals(dateFormat)){
+                // 按年统计
+                beginDate = DateUtils.firstDayOfYear(Integer.parseInt(beginDate)).format(
+                    DateTimeFormatter.ofPattern("yyyy-MM-dd" +" 00:00:00"));
+            }else if("yyyy-MM".equals(dateFormat)){
+                String[] dateArr = beginDate.split("-");
+                beginDate = DateUtils.firstDayOfMonth(Integer.parseInt(dateArr[0]), Integer.parseInt(dateArr[1])).format(
+                    DateTimeFormatter.ofPattern("yyyy-MM-dd" +" 00:00:00"));;
+            }else {
+                beginDate += " 00:00:00";
+            }
+        }
+        if(StringUtils.isNotBlank(endDate)){
+            if("yyyy".equals(dateFormat)){
+                // 按年统计
+                endDate = DateUtils.lastDayOfYear(Integer.parseInt(endDate)).format(
+                    DateTimeFormatter.ofPattern("yyyy-MM-dd" +" 23:59:59"));
+            }else if("yyyy-MM".equals(dateFormat)) {
+                String[] dateArr = endDate.split("-");
+                endDate = DateUtils.lastDayOfMonth(Integer.parseInt(dateArr[0]), Integer.parseInt(dateArr[1])).format(
+                    DateTimeFormatter.ofPattern("yyyy-MM-dd" + " 23:59:59"));
+            }else {
+                endDate += " 23:59:59";
+            }
+        }
+        return TableDataInfo.build(baseMapper.consumeAnalyze(pageQuery.build(),dateFormat, groupByTerm, accountIds,
+            roomIds,
+            beginDate, endDate));
+    }
+
 }

+ 42 - 0
ruoyi-modules/ruoyi-backstage/src/main/resources/mapper/consumption/XfConsumeDetailMapper.xml

@@ -46,4 +46,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <result property="updateBy"    column="update_by"    />
             <result property="updateTime"    column="update_time"    />
     </resultMap>
+
+    <select id="consumeAnalyze" resultType="org.dromara.backstage.consumption.domain.vo.XfConsumeAnalyzeVo">
+        select
+            account_name as accountName,
+            case when #{groupByTerm} then term_name else '所有机器' end as termName,
+            to_char(consume_date, #{dateFormat}) as consumeDate,
+            sum(case when meal_type = '1' and consume_money &gt; 0 then consume_money else 0 end) as zaoCanJinE,
+            sum(case when meal_type = '1' and consume_money &gt; 0 then 1 else 0 end) as zaoCanCiShu,
+            sum(case when meal_type = '2' and consume_money &gt; 0 then consume_money else 0 end) as wuCanJinE,
+            sum(case when meal_type = '2' and consume_money &gt; 0 then 1 else 0 end) as wuCanCiShu,
+            sum(case when meal_type = '3' and consume_money &gt; 0 then consume_money else 0 end) as wanCanJinE,
+            sum(case when meal_type = '3' and consume_money &gt; 0 then 1 else 0 end) as wanCanCiShu,
+            sum(case when meal_type = '4' and consume_money &gt; 0 then consume_money else 0 end) as xiaoYeJinE,
+            sum(case when meal_type = '4' and consume_money &gt; 0 then 1 else 0 end) as xiaoYeCiShu,
+            sum(case when consume_money &lt; 0 then consume_money else 0 end) as tuiKuanJinE,
+            sum(case when consume_money &lt; 0 then 1 else 0 end) as tuiKuanCiShu,
+            sum(case when consume_money &gt; 0 then consume_money else 0 end) as xiaoJiJinE,
+            sum(case when  consume_money &gt; 0 then 1 else 0 end) as xiaoJiCiShu
+        from
+            t_xf_consumeDetail
+        <where>
+            <if test="beginDate != null and beginDate != ''">
+                and consume_date &gt;= #{beginDate}
+            </if>
+            <if test="endDate != null and endDate != ''">
+                and consume_date &lt;= #{endDate}
+            </if>
+            <if test="accountIds != null and accountIds != ''">
+                and account_id in (#{accountIds})
+            </if>
+            <if test="roomIds != null and roomIds != ''">
+                and room_id in (#{roomIds})
+            </if>
+        </where>
+        group by
+            accountName,
+            termName,
+            consumeDate
+        order by
+            consumeDate,
+            accountName
+    </select>
 </mapper>