报表功能查看

This commit is contained in:
lizhenhua 2025-10-27 09:43:15 +08:00
parent 75075543d8
commit 2f132f8edc
8 changed files with 296 additions and 121 deletions

View File

@ -12,6 +12,7 @@ public class OrgConsume {
private BigDecimal canteenAmount = BigDecimal.ZERO; // 食堂消费
private BigDecimal superAmount = BigDecimal.ZERO; // 超市消费
private BigDecimal deductionAmount = BigDecimal.ZERO; // 补扣消费
private BigDecimal teabreakAmount = BigDecimal.ZERO; // 茶歇消费
//H5消费
private BigDecimal h5Amount = BigDecimal.ZERO;
private BigDecimal amount= BigDecimal.ZERO; //详情中都用这个字段做消费

View File

@ -11,6 +11,7 @@ public class ReportOrderInfoVo extends BaseEntity {
private String startTime;
private String endTime;
private int commonOrg ; // 1表示同组织0表示不同组织
private String[] selectedOrg;
private String[] gzselectedOrg;
@ -29,7 +30,7 @@ public class ReportOrderInfoVo extends BaseEntity {
private String orgName;
@Excel(name = "所属组织")
private String orgFullName;
@Excel(name = "交易")
@Excel(name = "交易")
private BigDecimal payableAmount;
private BigDecimal payableAmountAll;
private BigDecimal realAmount;

View File

@ -15,9 +15,12 @@ import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Set;
@RestController
@RequestMapping({"/api/v2/report"})
@ -114,6 +117,8 @@ public class reportformsController extends BaseController {
return service.getlistBySuperlist(orgConsume);
case 5:
return service.getDeductionlist(orgConsume);
case 6:
return service.getTeabreaklist(orgConsume);
default:
break;
}
@ -155,13 +160,22 @@ public class reportformsController extends BaseController {
*/
@PostMapping("/getplaceList")
public TableDataInfo getplaceList(@RequestBody ReportOrderInfoVo reportOrderInfoVo) {
int pageNum = reportOrderInfoVo.getPageNum() != null ? reportOrderInfoVo.getPageNum() : 1;
int pageSize = reportOrderInfoVo.getPageSize() != null ? reportOrderInfoVo.getPageSize() : 10;
int offset = (pageNum - 1) * pageSize;
int count =service.selectOrderMismatchListCount(reportOrderInfoVo);
List<ReportOrderInfoVo> list = service.selectOrderMismatchList(reportOrderInfoVo, offset, pageSize);
startPage();
List<ReportOrderInfoVo> list = service.selectOrderMismatchList(reportOrderInfoVo);
// 封装返回给前端
return new TableDataInfo(list, count);
return getDataTable(list);
}
/**
* 异地消费汇总
*
*/
@PostMapping("/getplacehzList")
public TableDataInfo getplacehzList(@RequestBody ReportOrderInfoVo reportOrderInfoVo) {
List<ReportOrderInfoVo> list = service.selectplaceHzList(reportOrderInfoVo);
// 封装返回给前端
return getDataTable(list);
}
/**
* 人员报表查询导出功能
@ -179,7 +193,7 @@ public class reportformsController extends BaseController {
e.printStackTrace();
}
}
checkCommonOrg(orgConsume);
// 1. 查询数据
List<ReportOrderInfoVo> peoplelist = service.placeexportExcel(orgConsume);
@ -195,5 +209,15 @@ public class reportformsController extends BaseController {
ExcelUtil<ReportOrderInfoVo> util = new ExcelUtil<>(ReportOrderInfoVo.class);
util.exportExcel(response, peoplelist, "人员导出数据详情");
}
private void checkCommonOrg(ReportOrderInfoVo vo) {
if (vo.getSelectedOrg() == null || vo.getGzselectedOrg() == null) {
vo.setCommonOrg(0);
return;
}
Set<String> set1 = new HashSet<>(Arrays.asList(vo.getSelectedOrg()));
Set<String> set2 = new HashSet<>(Arrays.asList(vo.getGzselectedOrg()));
vo.setCommonOrg(set1.equals(set2) ? 1 : 0);
}
}

View File

@ -6,6 +6,7 @@ import com.bonus.canteen.core.reportforms.beans.CanteenOrg;
import com.bonus.canteen.core.reportforms.beans.CanteenRecord;
import com.bonus.canteen.core.reportforms.beans.OrgConsume;
import com.bonus.canteen.core.reportforms.beans.ReportOrderInfoVo;
import io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2StreamFrame;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -49,13 +50,11 @@ public interface OrgConsumeMapper {
List<OrgConsume> getlistForH5Special(OrgConsume orgConsume);
List<ReportOrderInfoVo> selectOrderMismatchList( @Param("vo") ReportOrderInfoVo reportOrderInfoVo, @Param("offset")int offset, @Param("pageSize") int pageSize);
// 查询总数
int selectOrderMismatchListCount(ReportOrderInfoVo reportOrderInfoVo);
List<ReportOrderInfoVo> selectOrderMismatchList( @Param("vo") ReportOrderInfoVo reportOrderInfoVo);
ReportOrderInfoVo selectOrderMismatchListTotal(ReportOrderInfoVo reportOrderInfoVo);
List<CanteenOrg> selectAllareaOrgs();
List<OrgConsume> getTeabreaklist(OrgConsume orgConsume);
}

View File

@ -80,7 +80,10 @@ public class reportformsServiceImpl implements reportformsService {
oc.setCanteenAmount(oc.getCanteenAmount().add(amount));
} else if ("super".equals(conSource)) {
oc.setSuperAmount(oc.getSuperAmount().add(amount));
}else if("station".equals(conSource)){
}else if("teabreak".equals(conSource)){
oc.setTeabreakAmount(oc.getTeabreakAmount().add(amount));
}
else if("station".equals(conSource)){
//
//驿站支付sql查询无法达到目标从子表重新查询
// oc.setH5Amount(oc.getH5Amount().add(amount));
@ -150,28 +153,35 @@ public class reportformsServiceImpl implements reportformsService {
}
@Override
public List<ReportOrderInfoVo> selectOrderMismatchList(ReportOrderInfoVo reportOrderInfoVo, int pageNum, int pageSize) {
List<ReportOrderInfoVo> reportOrderInfoVos = mapper.selectOrderMismatchList(reportOrderInfoVo, pageNum, pageSize)
.stream()
.peek(c -> {
public List<ReportOrderInfoVo> selectOrderMismatchList(ReportOrderInfoVo reportOrderInfoVo) {
// 在查询前或查询后判断 selectedOrg / gzselectedOrg
checkCommonOrg(reportOrderInfoVo);
List<ReportOrderInfoVo> reportOrderInfoVos = mapper.selectOrderMismatchList(reportOrderInfoVo);
if (reportOrderInfoVos != null && !reportOrderInfoVos.isEmpty()) {
for (ReportOrderInfoVo c : reportOrderInfoVos) {
try {
// 姓名解密
if (c.getCustName() != null && !c.getCustName().isEmpty()) {
try {
c.setCustName(SM4EncryptUtils.sm4Decrypt(c.getCustName()));
if (c.getMobile() != null) {
String phone = SM4EncryptUtils.sm4Decrypt(c.getMobile());
if (phone.length() == 11) {
phone = phone.substring(0, 3) + "****" + phone.substring(7);
}
c.setMobile(phone);
}
c.setCustName(SM4EncryptUtils.sm4Decrypt(c.getCustName()));
}
} catch (Exception e) {
e.printStackTrace();
// 手机解密 + 脱敏
if (c.getMobile() != null && !c.getMobile().isEmpty()) {
String phone = SM4EncryptUtils.sm4Decrypt(c.getMobile());
if (phone.length() == 11) {
c.setMobile(phone.substring(0, 3) + "****" + phone.substring(7));
} else {
c.setMobile(phone);
}
}
})
.collect(Collectors.toList());
// 查询全表合计
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 查询全表合计
ReportOrderInfoVo totalVo = mapper.selectOrderMismatchListTotal(reportOrderInfoVo);
if (totalVo != null) {
ReportOrderInfoVo totalRow = new ReportOrderInfoVo();
@ -186,10 +196,27 @@ public class reportformsServiceImpl implements reportformsService {
return reportOrderInfoVos;
}
private static final String YUNJIAN_ORG_ID = "456681751578677248";
@Override
public int selectOrderMismatchListCount(ReportOrderInfoVo reportOrderInfoVo) {
return mapper.selectOrderMismatchListCount(reportOrderInfoVo);
private void checkCommonOrg(ReportOrderInfoVo vo) {
String[] selected = vo.getSelectedOrg();
String[] gzSelected = vo.getGzselectedOrg();
if (selected == null || gzSelected == null) {
vo.setCommonOrg(0);
return;
}
Set<String> set1 = new HashSet<>(Arrays.asList(selected));
Set<String> set2 = new HashSet<>(Arrays.asList(gzSelected));
// 特殊情况两个集合都包含运检分公司ID
boolean isYunjian = set1.contains(YUNJIAN_ORG_ID) && set2.contains(YUNJIAN_ORG_ID);
// 普通情况两个集合完全相同
boolean isSame = set1.equals(set2);
vo.setCommonOrg((isSame || isYunjian) ? 1 : 0);
}
@Override
@ -257,7 +284,6 @@ public class reportformsServiceImpl implements reportformsService {
// 去重退款记录flowType=130payTime相同保留第一次
Set<String> seenPayTimes = new HashSet<>();
orgConsumes.removeIf(c -> c.getFlowType() == 130 && !seenPayTimes.add(c.getPayTime()));
return orgConsumes;
}
@ -305,6 +331,7 @@ public class reportformsServiceImpl implements reportformsService {
@Override
public List<ReportOrderInfoVo> placeexportExcel(ReportOrderInfoVo orgConsume) {
checkCommonOrg(orgConsume);
List<ReportOrderInfoVo> reportOrderInfoVos = placemapper.placeexportExcel(orgConsume)
.stream()
.peek(c -> {
@ -325,12 +352,102 @@ public class reportformsServiceImpl implements reportformsService {
return reportOrderInfoVos;
}
@Override
public List<OrgConsume> getTeabreaklist(OrgConsume orgConsume) {
// 使用原有的查询逻辑
List<OrgConsume> orgConsumes = mapper.getTeabreaklist(orgConsume)
.stream()
.peek(c -> {
if (c.getCustName() != null && !c.getCustName().isEmpty()) {
try {
c.setCustName(SM4EncryptUtils.sm4Decrypt(c.getCustName()));
} catch (Exception e) {
e.printStackTrace();
}
}
})
.collect(Collectors.toList());
return orgConsumes;
}
@Override
public List<ReportOrderInfoVo> selectplaceHzList(ReportOrderInfoVo reportOrderInfoVo) {
checkCommonOrg(reportOrderInfoVo);
List<ReportOrderInfoVo> reportOrderInfoVos = mapper.selectOrderMismatchList(reportOrderInfoVo);
if (reportOrderInfoVos != null && !reportOrderInfoVos.isEmpty()) {
// ========== 第一步解密姓名和手机号 ==========
for (ReportOrderInfoVo c : reportOrderInfoVos) {
try {
// 姓名解密
if (c.getCustName() != null && !c.getCustName().isEmpty()) {
c.setCustName(SM4EncryptUtils.sm4Decrypt(c.getCustName()));
}
// 手机号解密 + 脱敏
if (c.getMobile() != null && !c.getMobile().isEmpty()) {
String phone = SM4EncryptUtils.sm4Decrypt(c.getMobile());
if (phone.length() == 11) {
c.setMobile(phone.substring(0, 3) + "****" + phone.substring(7));
} else {
c.setMobile(phone);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// ========== 第二步合并消费地与工作地相同的数据 ==========
Map<String, ReportOrderInfoVo> mergedMap = new LinkedHashMap<>();
for (ReportOrderInfoVo c : reportOrderInfoVos) {
// key = 消费地 + "_" + 工作地
String key = (c.getAreaName() == null ? "" : c.getAreaName()) + "_" +
(c.getWorkAreaName() == null ? "" : c.getWorkAreaName());
if (mergedMap.containsKey(key)) {
ReportOrderInfoVo exist = mergedMap.get(key);
// 交易次数累加int
exist.setTradeNum(exist.getTradeNum() + c.getTradeNum());
// 应付金额累加BigDecimal
if (exist.getPayableAmount() == null) {
exist.setPayableAmount(BigDecimal.ZERO);
}
if (c.getPayableAmount() != null) {
exist.setPayableAmount(exist.getPayableAmount().add(c.getPayableAmount()));
}
// 实付金额累加BigDecimal
if (exist.getRealAmount() == null) {
exist.setRealAmount(BigDecimal.ZERO);
}
if (c.getRealAmount() != null) {
exist.setRealAmount(exist.getRealAmount().add(c.getRealAmount()));
}
} else {
// 不存在则直接放入 map
mergedMap.put(key, c);
}
}
// 转换为列表返回
reportOrderInfoVos = new ArrayList<>(mergedMap.values());
}
return reportOrderInfoVos;
}
private List<CanteenOrg> buildAreaTree(List<CanteenOrg> list, Long parentId) {
System.err.println("parentId = " + parentId);
List<CanteenOrg> tree = new ArrayList<>();
for (CanteenOrg org : list) {
System.err.println("orgId=" + org.getOrgId() + ", superId=" + org.getSuperId());
if ((parentId == null && org.getSuperId() == null)
|| (parentId != null && parentId.equals(org.getSuperId()))) {
org.setChildren(buildAreaTree(list, org.getOrgId()));

View File

@ -24,12 +24,13 @@ public interface reportformsService {
List<OrgConsume> getDeductionlist(OrgConsume orgConsume);
List<ReportOrderInfoVo> selectOrderMismatchList(ReportOrderInfoVo reportOrderInfoVo,int pageNum, int pageSize);
int selectOrderMismatchListCount(ReportOrderInfoVo reportOrderInfoVo);
List<ReportOrderInfoVo> selectOrderMismatchList(ReportOrderInfoVo reportOrderInfoVo);
List<CanteenOrg> getOrgareatree();
List<ReportOrderInfoVo> placeexportExcel(ReportOrderInfoVo orgConsume);
List<OrgConsume> getTeabreaklist(OrgConsume orgConsume);
List<ReportOrderInfoVo> selectplaceHzList(ReportOrderInfoVo reportOrderInfoVo);
}

View File

@ -3,24 +3,27 @@
<mapper namespace="com.bonus.canteen.core.reportforms.mapper.OrgConsumeMapper">
<select id="selectConsumeRecords" resultType="java.util.Map">
SELECT
t.area_name AS areaName,
CASE
WHEN t.flow_type = 120 THEN 'deduction'
WHEN t.source_type = 7 THEN 'H5'
WHEN t.source_type = 53 THEN 'super'
WHEN t.device_name LIKE '%茶歇%' THEN 'teabreak'
WHEN (t.source_type IS NULL OR t.source_type = 0 OR t.source_type = '')
AND t.remark LIKE '%支付%' THEN 'station'
ELSE 'canteen'
END AS conSource,
ROUND(SUM(t.amount) / 100, 2) AS amount
FROM (
<!-- 正常消费 flow_type = 110 -->
-- ========= 正常消费 =========
SELECT
aac.area_name,
f.flow_type,
f.source_type,
f.remark,
di.device_name,
f.flow_real_amount AS amount,
f.flow_id
FROM report_account_flow f
@ -28,18 +31,20 @@
LEFT JOIN device_bind bd ON di.device_id = bd.device_id
LEFT JOIN alloc_canteen aa ON aa.canteen_id = bd.canteen_id
LEFT JOIN alloc_area aac ON aac.area_id = aa.area_id
WHERE f.pay_time <![CDATA[ >= ]]> #{startPayTime}
WHERE
f.pay_time <![CDATA[ >= ]]> #{startPayTime}
AND f.pay_time <![CDATA[ < ]]> #{endPayTime}
AND f.flow_type = 110
UNION ALL
<!-- 退款 flow_type = 130 -->
-- ========= 退款记录 =========
SELECT
aac.area_name,
130 AS flow_type,
f.source_type,
f.remark,
di.device_name,
AT.actual_amount AS amount,
f.flow_id AS origin_flow_id
FROM acc_trade AT
@ -50,7 +55,8 @@
LEFT JOIN device_bind bd ON di.device_id = bd.device_id
LEFT JOIN alloc_canteen aa ON aa.canteen_id = bd.canteen_id
LEFT JOIN alloc_area aac ON aac.area_id = aa.area_id
WHERE AT.trade_time <![CDATA[ >= ]]> #{startPayTime}
WHERE
AT.trade_time <![CDATA[ >= ]]> #{startPayTime}
AND AT.trade_time <![CDATA[ < ]]> #{endPayTime}
AND AT.trade_type = 130
AND AT.trade_state = 2
@ -58,12 +64,12 @@
UNION ALL
<!-- 补扣 flow_type = 120 -->
SELECT
aac.area_name,
f.flow_type,
f.source_type,
f.remark,
di.device_name,
f.flow_real_amount AS amount,
f.flow_id
FROM report_account_flow f
@ -71,8 +77,9 @@
LEFT JOIN device_bind bd ON di.device_id = bd.device_id
LEFT JOIN alloc_canteen aa ON aa.canteen_id = bd.canteen_id
LEFT JOIN alloc_area aac ON aac.area_id = aa.area_id
WHERE f.pay_time <![CDATA[ >= ]]> #{startPayTime}
AND f.pay_time <![CDATA[ < ]]> #{endPayTime}
WHERE
f.pay_time <![CDATA[ >= ]]> #{startPayTime}
AND f.pay_time <![CDATA[ < ]]> #{endPayTime}
AND f.flow_type = 120
) t
GROUP BY
@ -81,11 +88,14 @@
WHEN t.flow_type = 120 THEN 'deduction'
WHEN t.source_type = 7 THEN 'H5'
WHEN t.source_type = 53 THEN 'super'
WHEN t.device_name LIKE '%茶歇%' THEN 'teabreak'
WHEN (t.source_type IS NULL OR t.source_type = 0 OR t.source_type = '')
AND t.remark LIKE '%支付%' THEN 'station'
ELSE 'canteen'
END
ORDER BY t.area_name
ORDER BY
t.area_name;
</select>
<select id="selectReserveRecords" resultType="java.util.Map">
@ -906,7 +916,10 @@
JOIN cust_dining_place p ON p.cust_id = ci.cust_id AND p.type = 'area'
LEFT JOIN alloc_area ar ON ar.area_id = a.area_id
LEFT JOIN alloc_area ap ON ap.area_id = p.dining_place_id
WHERE ar.area_id != p.dining_place_id
where 1=1
<if test="vo.commonOrg != 1">
and ar.area_id != p.dining_place_id
</if>
<!-- 判断消费地 -->
<if test="vo.selectedOrg != null and vo.selectedOrg.length > 0">
AND ar.area_id IN
@ -924,76 +937,9 @@
) a
GROUP BY cust_id, area_name, work_area_name, order_type
ORDER BY MAX(a.pay_time) DESC
LIMIT #{offset}, #{pageSize}
</select>
<!-- 查询总数 -->
<select id="selectOrderMismatchListCount" resultType="int">
SELECT COUNT(1) FROM (
SELECT
a.cust_id,
ac.area_id,
ac.canteen_type,
p.dining_place_id
FROM (
select a.flow_id as order_id, a.cust_id,a.flow_amount as payable_amount,a.flow_real_amount as real_amount,a.pay_time,
case when bd.area_id is not null then bd.area_id when ac.area_id is not null then ac.area_id
when cdp.dining_place_id is not null then cdp.dining_place_id
else a.canteen_id end as area_id,CONCAT(a.cust_id,a.ord_time) as id
,case when bd.canteen_id is not null then bd.canteen_id when roi.canteen_id is not null then roi.canteen_id
else a.canteen_id end as canteen_id
,a.mch_sn as mch_sn
from (select * from report_account_flow a where a.pay_time >= #{startTime} AND a.flow_type IN ( 110, 120 )
AND a.pay_time &lt;= #{endTime} ) a
LEFT JOIN device_info di ON a.mch_sn = di.device_sn
LEFT JOIN device_bind bd ON di.device_id = bd.device_id
LEFT JOIN (select * from report_order_info a where a.pay_time >= #{startTime}
AND a.pay_time &lt;= #{endTime} ) roi on CONCAT(a.cust_id,a.ord_time)=CONCAT(roi.cust_id,roi.order_time)
LEFT JOIN alloc_canteen ac ON ac.canteen_id = roi.canteen_id
left join cust_dining_place cdp on a.cust_id=cdp.cust_id and cdp.type = 'area'
union
select a.flow_id as order_id, a.cust_id,a.flow_amount as payable_amount,a.flow_real_amount as real_amount,a.pay_time,
case when bd.area_id is not null then bd.area_id when ac.area_id is not null then ac.area_id
when cdp.dining_place_id is not null then cdp.dining_place_id
else a.canteen_id end as area_id,CONCAT(a.cust_id,a.ord_time) as id
,case when bd.canteen_id is not null then bd.canteen_id when roi.canteen_id is not null then roi.canteen_id
else a.canteen_id end as canteen_id
,a.mch_sn as mch_sn
from (select * from report_account_flow a where a.pay_time >= #{startTime} AND a.flow_type IN ( 130 )
AND a.pay_time &lt;= #{endTime} ) a
left join acc_trade atr on a.flow_id=atr.id
left join (select * from report_account_flow a where a.pay_time >= #{startTime} AND a.flow_type IN ( 110, 120 )
AND a.pay_time &lt;= #{endTime} ) aa on atr.origin_trade_id=aa.flow_id
LEFT JOIN device_info di ON aa.mch_sn = di.device_sn
LEFT JOIN device_bind bd ON di.device_id = bd.device_id
LEFT JOIN (select * from report_order_info a where a.pay_time >= #{startTime}
AND a.pay_time &lt;= #{endTime} ) roi on CONCAT(aa.cust_id,a.ord_time)=CONCAT(roi.cust_id,roi.order_time)
LEFT JOIN alloc_canteen ac ON ac.canteen_id = roi.canteen_id
left join cust_dining_place cdp on aa.cust_id=cdp.cust_id and cdp.type = 'area'
) a
LEFT JOIN alloc_canteen ac ON ac.canteen_id = a.canteen_id
JOIN cust_info ci ON ci.cust_id = a.cust_id
LEFT JOIN alloc_area ar ON ar.area_id = a.area_id
JOIN cust_dining_place p ON p.cust_id = ci.cust_id AND p.type = 'area'
WHERE ar.area_id != p.dining_place_id
<!-- 判断消费地 -->
<if test="selectedOrg != null and selectedOrg.length > 0">
AND ar.area_id IN
<foreach collection="selectedOrg" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
<!-- 判断工作地 -->
<if test="gzselectedOrg != null and gzselectedOrg.length > 0">
AND p.dining_place_id IN
<foreach collection="gzselectedOrg" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
GROUP BY a.cust_id, ac.area_id, p.dining_place_id,ac.canteen_type
) t
</select>
<select id="selectOrderMismatchListTotal"
resultType="com.bonus.canteen.core.reportforms.beans.ReportOrderInfoVo">
SELECT
@ -1054,7 +1000,10 @@
LEFT JOIN cust_info ci ON ci.cust_id = a.cust_id
LEFT JOIN alloc_area ar ON ar.area_id = a.area_id
JOIN cust_dining_place p ON p.cust_id = ci.cust_id AND p.type = 'area'
WHERE ar.area_id != p.dining_place_id
where 1=1
<if test="commonOrg != 1">
and ar.area_id != p.dining_place_id
</if>
<!-- 判断消费地 -->
<if test="selectedOrg != null and selectedOrg.length > 0">
AND ar.area_id IN
@ -1072,6 +1021,7 @@
</if>
) a
) t
</select>
<select id="selectAllareaOrgs" resultType="com.bonus.canteen.core.reportforms.beans.CanteenOrg">
SELECT
@ -1087,4 +1037,84 @@
resultType="com.bonus.canteen.core.reportforms.beans.ReportOrderInfoVo">
</select>
<select id="getTeabreaklist" resultType="com.bonus.canteen.core.reportforms.beans.OrgConsume">
SELECT
co.org_full_name AS orgFullName,
u.cust_name,
u.cust_name_like,
t.canteen_name,
t.area_name,
'teabreak' AS consume_source,
t.flow_id,
t.flow_type,
CASE
WHEN t.flow_type = 110 THEN '消费'
WHEN t.flow_type = 130 THEN '退款'
ELSE '其他'
END AS flow_type_name,
t.flow_real_amount / 100 AS amount,
t.ord_time,
t.pay_time,
t.walletId,
t.remark
FROM (
-- ========= 茶歇消费记录 =========
SELECT
aa.canteen_name,
aac.area_name,
f.flow_id,
d.flow_type,
f.flow_real_amount,
f.ord_time,
d.pay_time,
f.cust_id,
atwd.wallet_id AS walletId,
f.remark
FROM report_account_flow f
LEFT JOIN acc_trade_wallet_detail atwd ON atwd.trade_id = f.flow_id
INNER JOIN report_account_flow_detail d ON f.flow_id = d.flow_id
LEFT JOIN device_info di ON f.mch_sn = di.device_sn
LEFT JOIN device_bind bd ON di.device_id = bd.device_id
LEFT JOIN alloc_canteen aa ON aa.canteen_id = bd.canteen_id
LEFT JOIN alloc_area aac ON aac.area_id = aa.area_id
WHERE d.pay_time >= #{startPayTime}
AND d.pay_time &lt;#{endPayTime}
AND d.flow_type = 110
AND di.device_name LIKE '%茶歇%' -- ✅ 茶歇设备过滤
UNION ALL
-- ========= 茶歇退款记录 =========
SELECT
aa.canteen_name,
aac.area_name,
f.flow_id,
130 AS flow_type,
at.actual_amount AS flow_real_amount,
f.ord_time,
at.trade_time AS pay_time,
f.cust_id,
atwd.wallet_id AS walletId,
f.remark
FROM report_account_flow f
INNER JOIN acc_trade at
ON at.cust_id = f.cust_id
AND at.trade_type = 130
AND DATE(at.trade_time) = DATE(f.pay_time)
AND at.actual_amount = -f.flow_real_amount
LEFT JOIN acc_trade_wallet_detail atwd ON atwd.trade_id = f.flow_id
LEFT JOIN device_info di ON f.mch_sn = di.device_sn
LEFT JOIN device_bind bd ON di.device_id = bd.device_id
LEFT JOIN alloc_canteen aa ON aa.canteen_id = bd.canteen_id
LEFT JOIN alloc_area aac ON aac.area_id = aa.area_id
WHERE at.trade_time >= #{startPayTime}
AND at.trade_time &lt; #{endPayTime}
AND di.device_name LIKE '%茶歇%'
) t
LEFT JOIN cust_info u ON t.cust_id = u.cust_id
LEFT JOIN cust_org co ON u.org_id = co.org_id
WHERE t.area_name LIKE CONCAT('%', #{orgName}, '%')
ORDER BY t.pay_time DESC;
</select>
</mapper>

View File

@ -10,7 +10,6 @@
ANY_VALUE(org_name) AS org_name,
ANY_VALUE(org_full_name) AS org_full_name,
COUNT(1) AS tradeNum,
order_type,
SUM(real_amount) AS payable_amount,
SUM(real_amount) AS real_amount,
area_name,
@ -75,7 +74,10 @@
JOIN cust_dining_place p ON p.cust_id = ci.cust_id AND p.type = 'area'
LEFT JOIN alloc_area ar ON ar.area_id = a.area_id
LEFT JOIN alloc_area ap ON ap.area_id = p.dining_place_id
WHERE ar.area_id != p.dining_place_id
where 1=1
<if test="commonOrg != 1">
and ar.area_id != p.dining_place_id
</if>
<!-- 判断消费地 -->
<if test="selectedOrg != null and selectedOrg.length > 0">
AND ar.area_id IN
@ -91,7 +93,7 @@
</foreach>
</if>
) a
GROUP BY cust_id, area_name, work_area_name, order_type
GROUP BY cust_id, area_name, work_area_name
ORDER BY MAX(a.pay_time) DESC
</select>
</mapper>