Compare commits

..
43 Commits
Author SHA1 Message Date
hejiayang 5307f30fd8 消费统计时间来源调整 2026-01-29 09:24:05 +08:00
hejiayang f2d53786c2 充值记录 ,按照升序排序 2026-01-08 15:40:23 +08:00
hejiayang 712f295d57 Merge remote-tracking branch 'origin/master' 2026-01-07 14:53:36 +08:00
hejiayang e39496cca1 用户余额心跳调整 2026-01-07 14:53:17 +08:00
fansongsong f48d94227b 1:调整流水明细-统计+导出 使用列表查询统一sql
2:个人消费统计调整关联sys_user_sub使用LEFT JOIN解决和消费明细统计数据不一致问题
3:调整订单生成策略避免并发场景重复问题
2025-12-26 18:32:05 +08:00
hejiayang 9be9985905 人脸激活码配置
虹软识别人脸特征码失败后,将错误信息返回给前端
2025-12-25 14:57:32 +08:00
fansongsong 950d7999cb 消费明细报表-导出,调整字段顺序7 2025-12-22 15:16:20 +08:00
hejiayang 2527c5e765 线上配置数据库调整 2025-12-22 13:47:30 +08:00
fansongsong ef4b27f560 消费明细报表-导出,调整字段顺序6 2025-12-19 16:50:43 +08:00
fansongsong 3500408271 消费明细报表-导出,调整字段顺序6 2025-12-19 11:57:56 +08:00
hejiayang 1ec8f5ad62 部门列表筛选公共方法优化 2025-12-19 11:52:48 +08:00
fansongsong 515b231718 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/payment/controller/StBbzxOrderInfoController.java
2025-12-19 11:16:20 +08:00
fansongsong fcf1d0f5f4 消费明细报表-导出,调整字段顺序5 2025-12-19 11:14:13 +08:00
hejiayang 5c7dd646a6 Merge remote-tracking branch 'origin/master' 2025-12-19 11:13:18 +08:00
fansongsong 2fcd14b4f1 消费明细报表-导出,调整字段顺序4 2025-12-15 10:54:50 +08:00
fansongsong ca26e9bc1f 消费明细报表-导出,调整字段顺序3 2025-12-15 10:16:34 +08:00
fansongsong a27f23c88d 消费明细报表-导出,调整字段顺序2 2025-12-15 10:15:47 +08:00
hejiayang 60cf42b4c2 Merge remote-tracking branch 'origin/master' 2025-12-15 10:13:58 +08:00
fansongsong 28d560acda 消费明细报表-导出,调整字段顺序 2025-12-15 10:12:31 +08:00
hejiayang a939ff4f4b 鉴权相关操作还原 2025-12-15 09:10:22 +08:00
hejiayang 8763fd66e6 流水明细相关鉴权回滚 2025-12-12 12:06:42 +08:00
hejiayang 7ac528635f 消费流水 部门筛选调整 2025-12-12 12:01:27 +08:00
hejiayang e364fad645 取消鉴权操作
1. 流水明细
2. 充值记录
3. 个人消费统计
4. 食堂消费统计
2025-12-11 17:01:49 +08:00
hejiayang e94886989a getRemark余额调整 2025-12-09 16:10:18 +08:00
hejiayang 35802ddc3b 余额调整,用户id赋值bug,交易记录交易金额计算bug 2025-12-09 14:34:59 +08:00
hejiayang 8141d18a9b 充值流水+setPayMemberId-解决充值记录联查用户名为空问题 2025-12-08 11:56:18 +08:00
hejiayang 09cf5771c4 充值流水 名字回显bug 2025-12-07 12:38:55 +08:00
hejiayang 84f5eaad9b 新功能及bug修改 2025-12-06 20:48:38 +08:00
hejiayang 4614ed1f19 新功能及bug修改 2025-12-06 20:13:50 +08:00
hejiayang a9128bcc60 bug 2025-12-06 19:40:13 +08:00
hejiayang fb78ec7693 异常消费流水导出 2025-12-06 15:23:04 +08:00
hejiayang a7d9efebbf 1.消费流水明细/充值流水优化
2.消费流水导出没有数据 bug
3.异常扣费数据保存, 页面回显
4.扣费闸机在线扣费异常信息返回调整
5.二次扣费,自定义扣费 不去校验用户本餐是否就餐
2025-12-06 15:08:30 +08:00
hejiayang 832bae83d1 代码回滚, 前端已处理此逻辑 2025-12-04 17:32:35 +08:00
hejiayang 67bdd7159a 员工充值筛选调整 2025-12-04 17:30:04 +08:00
hejiayang 30d7b4f52d 设备状态判断bug 2025-11-30 12:32:52 +08:00
hejiayang 46476badc7 新功能及bug修改 2025-11-29 20:54:54 +08:00
hejiayang b10310a8fa 六厂财务系统离线功能完善 2025-11-21 15:05:33 +08:00
hejiayang 17ec682f03 bug 2025-11-21 08:39:45 +08:00
hejiayang 02f96eecc3 六厂财务系统离线功能完善 2025-11-20 18:30:45 +08:00
hejiayang ac6bfdf437 bug修改 2025-10-28 17:25:21 +08:00
hejiayang 5b17317fd9 充值列表接口时间筛选调整: 余: 用 最后一次消费时间 筛选 2025-10-27 19:03:06 +08:00
hejiayang 660a713a7d 闸机扣费接口调整 2025-10-27 18:06:42 +08:00
hejiayang 9e7c1b4495 编辑用户(如果类型变更,更新用户钱包)
列表回显调整
2025-10-27 11:35:55 +08:00
69 changed files with 2461 additions and 361 deletions
@@ -445,4 +445,12 @@ public interface CommonConstant {
// 食堂支付人脸数据键名 // 食堂支付人脸数据键名
String FACE_CACHE_PAY = "FACE_CACHE_PAY"; String FACE_CACHE_PAY = "FACE_CACHE_PAY";
/**
* 设备状态缓存 key: 设备编号 value 时间戳
*/
String DEVICE_STATUS = "device_status";
/**
* 下发信息缓存 key: 设备编号
*/
String ISSUE_INFORMATION = "issue_information";
} }
@@ -0,0 +1,73 @@
package org.jeecg.common.util;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Component
public class RedisLockUtil {
private final StringRedisTemplate stringRedisTemplate;
// 锁的默认过期时间:1分钟
private static final long DEFAULT_LOCK_EXPIRE = 60;
// 锁的前缀,避免键名冲突
private static final String LOCK_PREFIX = "food:lock:";
public RedisLockUtil(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
/**
* 获取分布式锁
* @param key 业务键(这里使用菜品ID)
* @return 锁标识(释放锁时需要),null表示获取锁失败
*/
public String tryLock(String key) {
return tryLock(key, DEFAULT_LOCK_EXPIRE, TimeUnit.SECONDS);
}
/**
* 获取分布式锁
* @param key 业务键
* @param expire 过期时间
* @param timeUnit 时间单位
* @return 锁标识,null表示获取锁失败
*/
public String tryLock(String key, long expire, TimeUnit timeUnit) {
// 生成唯一标识,用于释放锁时的验证
String lockValue = UUID.randomUUID().toString();
String lockKey = LOCK_PREFIX + key;
// 使用setIfAbsent实现分布式锁,原子操作
Boolean success = stringRedisTemplate.opsForValue()
.setIfAbsent(lockKey, lockValue, expire, timeUnit);
return Boolean.TRUE.equals(success) ? lockValue : null;
}
/**
* 释放分布式锁
* @param key 业务键
* @param lockValue 获取锁时返回的标识
* @return 是否释放成功
*/
public boolean releaseLock(String key, String lockValue) {
if (lockValue == null) {
return false;
}
String lockKey = LOCK_PREFIX + key;
String currentValue = stringRedisTemplate.opsForValue().get(lockKey);
// 验证是否是自己持有的锁
if (lockValue.equals(currentValue)) {
// 执行删除操作
return Boolean.TRUE.equals(stringRedisTemplate.delete(lockKey));
}
return false;
}
}
@@ -10,5 +10,13 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>jeecg-system-local-api</artifactId> <artifactId>jeecg-system-local-api</artifactId>
<dependencies>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.7.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project> </project>
@@ -104,4 +104,12 @@ public class CqBaseEmpVo extends CqBaseEmployee implements Serializable {
//直接部门ID //直接部门ID
private String departIds; private String departIds;
/**
* 身份证号
*/
private String cardNo;
/**
* 手机号
*/
private String phoneNum;
} }
@@ -0,0 +1,62 @@
package org.jeecg.emp.vo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class StUserBalanceVo {
/**
* 用户id
*/
private String id;
/**
* 姓名
*/
private String realname;
/**
* 卡号
*/
private String cardCode;
/**
* 卡状态
*/
private String cardCodeStatus;
/**
* 卡状态
*/
private String cardCodeStatusName;
/**
* 电话
*/
private String phone;
/**
* 工号
*/
private String workNo;
/**
* 身份证号
*/
private String cardNo;
/**
* 部门id
*/
private String departIds;
/**
* 用户类型 0正式 1非正式 2家庭成员
*/
private String userType;
/**
* 家庭成员 对应主用户id
*/
private String mainUserId;
/**
* 食堂id
*/
private String canteenId;
/**
* 账户余额
*/
private BigDecimal balance;
}
@@ -0,0 +1,16 @@
package org.jeecg.equipment.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class StEquipmentDto {
@Schema(title = "设备名称编码")
private String appPackageLocalUrl;
@Schema(title = "所在位置")
private String placement;
@Schema(title = "备注")
private String remark;
}
@@ -0,0 +1,63 @@
package org.jeecg.equipment.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.io.Serializable;
import java.util.Date;
/**
* @Description: 设备管理表
* @Author: jeecg-boot
* @Date: 2022-08-30
* @Version: V1.0
*/
@Data
@TableName("st_canteen_equipment")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Tag(name="st_canteen_equipment对象", description="食堂设备表")
public class StCanteenEquipment implements Serializable {
private static final long serialVersionUID = 1L;
/**主键*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(title = "设备编码")
private String equipmentCode;
/**食堂id*/
@Schema(title = "食堂id")
private String canteenId;
@Schema(title = "设备ip")
private String equipmentIp;
/**
* 本地人脸数
*/
@Schema(title = "本地人脸数")
private Integer faceNum;
/**
* 设备剩余存储量
*/
@Schema(title = "设备剩余存储量")
private String availableMemory;
/**创建日期*/
@Schema(title = "创建日期")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**更新日期*/
@Schema(title = "更新日期")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -117,4 +117,10 @@ public class StEquipment implements Serializable {
/**所属餐道餐道中的顺序*/ /**所属餐道餐道中的顺序*/
@Schema(title = "所属餐道餐道中的顺序") @Schema(title = "所属餐道餐道中的顺序")
private Integer owningTrackOrder; private Integer owningTrackOrder;
@Schema(title = "所在位置")
private String placement;
@Schema(title = "备注")
private String remark;
} }
@@ -19,6 +19,8 @@ public class StClientMemberTransactionRecordDTO {
@DateTimeFormat(pattern="yyyy-MM-dd") @DateTimeFormat(pattern="yyyy-MM-dd")
@Schema(title ="就餐时间") @Schema(title ="就餐时间")
private String mainTimeDay; private String mainTimeDay;
private String startDate;
private String endDate;
private String startTime; private String startTime;
@@ -82,4 +84,9 @@ public class StClientMemberTransactionRecordDTO {
//直接部门ID //直接部门ID
private String departId; private String departId;
@Schema(title ="餐次")
private String dinnerType;
private List<String> canteenIdList;
} }
@@ -0,0 +1,54 @@
package org.jeecg.payment.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import org.jeecg.common.system.vo.ScreenVo;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
*/
@Data
@Tag(name= "StExceptionRecordDTO对象", description = "消费异常记录")
public class StExceptionRecordDTO {
/**
* 时间区间
*/
private List<String> dates;
private String startTime;
private String endTime;
@Schema(title ="手机号")
private String phone;
@Schema(title ="会员姓名")
private String userName;
@Schema(title ="工号")
private String workNo;
@Schema(title ="卡号")
private String cardCode;
//直接部门ID
private String departId;
@Schema(title="部门集合")
private List<String> list;
@Schema(title ="当前页")
private Integer pageNo;
@Schema(title ="数量/页")
private Integer pageSize;
private String startDate;
private String endDate;
private String canteenId;
List<String> canteenIdList;
}
@@ -43,6 +43,10 @@ public class StBbzxOrderInfo extends JeecgEntity implements Serializable {
@Schema(title ="餐次名称") @Schema(title ="餐次名称")
private String dinnerType; private String dinnerType;
@Schema(title ="设备编码")
private String deviceCode;
/** /**
* 经营模式、扣费类型(1:固定扣费,2:固定+补贴扣费,3:按量扣费) * 经营模式、扣费类型(1:固定扣费,2:固定+补贴扣费,3:按量扣费)
*/ */
@@ -38,6 +38,9 @@ public class StClientMemberTransactionRecord extends JeecgEntity implements Seri
@Schema(title ="交易流水号") @Schema(title ="交易流水号")
private String serialNo; private String serialNo;
@Schema(title ="设备编码")
private String deviceCode;
/** /**
* 订单号 * 订单号
*/ */
@@ -0,0 +1,69 @@
/**
* use shuwei code generator created
*/
package org.jeecg.payment.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Data
@TableName("st_consumption_exception_record")
@EqualsAndHashCode(callSuper = false)
@Tag(name= "StConsumptionExceptionRecord对象", description = "异常消费流水")
public class StConsumptionExceptionRecord implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(title ="ID")
private String id;
@Schema(title ="用户id")
private String userId;
@Schema(title ="设备编码")
private String deviceCode;
@Schema(title ="食堂ID")
private String canteenId;
@Schema(title ="卡号")
private String cardCode;
@Schema(title ="支付唯一id")
private String payId;
@Schema(title ="消费时间(时间戳)")
private String dateTime;
@Schema(title ="消费时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date payTime;
@Schema(title ="消费金额")
private BigDecimal spendMoney;
@Schema(title ="二次扣费标记 1 是; 0 否")
private Integer secondChargeFlag;
@Schema(title ="自定义扣费标记 1 是 ; 0 否")
private Integer isCustom;
@Schema(title ="恢复标记 1 是; 0 否; 3 不展示恢复标记")
private Integer isRestore;
@Schema(title ="异常提示")
private String errorMsg;
/**创建日期*/
@Schema(title = "创建日期")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**更新日期*/
@Schema(title = "更新日期")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}
@@ -0,0 +1,34 @@
package org.jeecg.payment.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class StCanteenEquipmentVo {
@Schema(description = "食堂id")
private String canteenId;
@Schema(description = "食堂名称")
private String restName;
@Schema(description = "设备名称")
private String equipmentName;
@Schema(description = "设备编码")
private String equipmentCode;
@Schema(description = "设备编码(前端展示)")
private String appPackageLocalUrl;
@Schema(description = "所在位置")
private String placement;
@Schema(description = "设备描述")
private String remark;
@Schema(description = "设备ip")
private String equipmentIp;
@Schema(description = "本地人脸数")
private Integer faceNum;
@Schema(description = "设备剩余存储量")
private String availableMemory;
@Schema(description = "设备状态: 0离线 1在线")
private String status;
@Schema(description = "上传数量")
private Integer totalNum;
}
@@ -9,8 +9,10 @@ import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data; import lombok.Data;
import org.jeecg.common.system.base.entity.JeecgEntity; import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecg.restaurant.entity.SlBaseDinnerTime;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
/** /**
* 扣费规则 * 扣费规则
@@ -66,4 +68,6 @@ public class StClientMemberLevelDeductRuleVo extends JeecgEntity implements Seri
@Schema(title = "是否支持透支消费(0:不支持,1:支持)") @Schema(title = "是否支持透支消费(0:不支持,1:支持)")
private Integer isOverdraftDine; private Integer isOverdraftDine;
private List<SlBaseDinnerTime> dinnerTimes;
} }
@@ -0,0 +1,53 @@
package org.jeecg.payment.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.jeecg.common.util.BigDecimalSerialize;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class StExceptionRecordVo {
@Schema(title ="id")
private String id;
@Schema(title ="卡号")
private String cardCode;
@Schema(title ="会员姓名")
private String userName;
@Schema(title ="会员电话")
private String phone;
@Schema(title ="工号")
private String workNo;
@Schema(title ="本次扣费金额")
private BigDecimal spendMoney;
@Schema(title ="自定义扣费标记 1 是 ; 0 否")
private Integer isCustom;
@Schema(title ="恢复标记 1 已恢复; 0 否")
private Integer isRestore;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(title ="消费时间")
private Date payTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(title ="数据上传时间")
private Date createTime;
@Schema(title ="食堂名称")
private String restName;
@Schema(title ="餐次名称")
private String dinnerType;
@Schema(title ="部门名称")
private String deptName;
private String errorMsg;
}
@@ -0,0 +1,14 @@
package org.jeecg.payment.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class StRecordNumVo {
@Schema(description = "数量")
private Integer num;
@Schema(description = "设备编码")
private String deviceCode;
}
@@ -1,5 +1,6 @@
package org.jeecg.payment.vo; package org.jeecg.payment.vo;
import com.opencsv.bean.CsvBindByName;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
@@ -14,6 +15,7 @@ import java.math.BigDecimal;
@Data @Data
public class StRfidVo { public class StRfidVo {
// @NotEmpty(message = "用户ID不能为空") // @NotEmpty(message = "用户ID不能为空")
@CsvBindByName(column = "user_id")
private String userId; private String userId;
@NotEmpty(message = "设备编码不能为空") @NotEmpty(message = "设备编码不能为空")
private String deviceCode; private String deviceCode;
@@ -22,16 +24,37 @@ public class StRfidVo {
/** /**
* 卡号 * 卡号
*/ */
@CsvBindByName(column = "card_code")
private String cardCode; private String cardCode;
/** /**
* 闸机记录的支付唯一id(用于判断防止重复支付的标记) * 闸机记录的支付唯一id(用于判断防止重复支付的标记)
*/ */
@CsvBindByName(column = "pay_id")
private String payId; private String payId;
//===离线扣费场景参数 //===离线扣费场景参数
//消费时间(时间戳) //消费时间(时间戳)
@CsvBindByName(column = "date_time")
private String dateTime; private String dateTime;
//本次扣费金额(后端根据规则计算) //本次扣费金额(后端根据规则计算)
@CsvBindByName(column = "spend_money")
private BigDecimal spendMoney; private BigDecimal spendMoney;
/**
* 二次扣费标记 1 是; 0 否
*/
@CsvBindByName(column = "second_charge_flag")
private Integer secondChargeFlag;
/**
* 自定义扣费标记 1 是 ; 0 否
*/
@CsvBindByName(column = "is_custom")
private Integer isCustom;
/**
* 恢复标记 1 是; 0 否
*/
private Integer isRestore;
private String errorMsg;
} }
@@ -0,0 +1,20 @@
package org.jeecg.system.vo;
import lombok.Data;
import org.jeecg.user.entity.StUserFaceimgSubIncremInfo;
import java.util.List;
@Data
public class SwHeartbeatFaceVo {
/**
* 是否下发
*/
private boolean isIssue;
/**
* 人脸数据
*/
private List<StUserFaceimgSubIncremInfo> faceList;
}
@@ -127,6 +127,18 @@ public class CqBaseEmployeePayController extends JeecgController<CqBaseEmployee,
return cqBaseEmployeeService.saveEmpSub(sysUserSub); return cqBaseEmployeeService.saveEmpSub(sysUserSub);
} }
@AutoLog(value = "主用户编辑")
@Operation(summary = "主用户编辑", description = "主用户编辑")
@PutMapping(value = "/updateMainUserSubInfo")
public Result<?> updateMainUserSubInfo(@RequestBody SysUserSub sysUserSub){
if(StringUtils.isBlank(sysUserSub.getId())){
return Result.error("用户ID不能为空");
}
Result<?> result = cqBaseEmployeeService.updateMainUserSubInfo(sysUserSub);
Map<String, Object> stringMap = new HashMap<>();
stringMap.put("userId", sysUserSub.getId());
return result;
}
/** /**
* 非正式、家庭用户编辑 * 非正式、家庭用户编辑
@@ -237,4 +249,85 @@ public class CqBaseEmployeePayController extends JeecgController<CqBaseEmployee,
return Result.OK("删除成功!"); return Result.OK("删除成功!");
} }
@AutoLog(value = " 非正式+正式员工绑卡")
@Operation(summary = " 非正式+正式员工绑卡", description = " 非正式+正式员工绑卡")
@PostMapping(value = "/editBuildCardCode")
public Result<?> editBuildCardCode(@RequestBody SysUserSub sysUserSub) {
if(StringUtils.isBlank(sysUserSub.getId())){
return Result.error("用户ID不能为空");
}
if(StringUtils.isBlank(sysUserSub.getCardCode())){
return Result.error("卡号不能为空");
}
SysUserSub sysUserSub1 = sysUserSubService.getById(sysUserSub.getId());
if(null == sysUserSub1){
return Result.error("用户不存在");
}
//家庭用户
if(sysUserSub1.getUserType() == 2){
return Result.error("家庭用户不支持操作");
}
sysUserSub.setCardCodeStatus(1);
Result<?> result = cqBaseEmployeeService.updateEmpSub(sysUserSub);
return result;
}
/**
* 非正式+正式员工解绑卡
*
* @return
*/
@AutoLog(value = " 非正式+正式员工解绑卡")
@Operation(summary = " 非正式+正式员工解绑卡", description = " 非正式+正式员工解绑卡")
@PostMapping(value = "/editUnBuildCardCode")
public Result<?> editUnBuildCardCode(@RequestBody SysUserSub sysUserSub) {
if(StringUtils.isBlank(sysUserSub.getId())){
return Result.error("用户ID不能为空");
}
if(StringUtils.isBlank(sysUserSub.getCardCode())){
return Result.error("卡号不能为空");
}
SysUserSub sysUserSub1 = sysUserSubService.getById(sysUserSub.getId());
if(null == sysUserSub1){
return Result.error("用户不存在");
}
//家庭用户
if(sysUserSub1.getUserType() == 2){
return Result.error("家庭用户不支持操作");
}
sysUserSub.setCardCodeStatus(3);
sysUserSub.setCardCode("");
Result<?> result = cqBaseEmployeeService.updateEmpSub(sysUserSub);
return result;
}
/**
* 非正式+正式员工挂失
*
* @return
*/
@AutoLog(value = " 非正式+正式员工挂失")
@Operation(summary = " 非正式+正式员工挂失", description = " 非正式+正式员工挂失")
@PostMapping(value = "/editBuildCardCodeLoss")
public Result<?> editBuildCardCodeLoss(@RequestBody SysUserSub sysUserSub) {
if(StringUtils.isBlank(sysUserSub.getId())){
return Result.error("用户ID不能为空");
}
if(StringUtils.isBlank(sysUserSub.getCardCode())){
return Result.error("卡号不能为空");
}
SysUserSub sysUserSub1 = sysUserSubService.getById(sysUserSub.getId());
if(null == sysUserSub1){
return Result.error("用户不存在");
}
//家庭用户
if(sysUserSub1.getUserType() == 2){
return Result.error("家庭用户不支持操作");
}
sysUserSub.setCardCodeStatus(2);
Result<?> result = cqBaseEmployeeService.updateEmpSub(sysUserSub);
return result;
}
} }
@@ -1,15 +1,13 @@
package org.jeecg.emp.mapper; package org.jeecg.emp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import org.jeecg.emp.entity.CqBaseEmployee; import org.jeecg.emp.entity.CqBaseEmployee;
import org.jeecg.emp.vo.CqBaseEmpVo; import org.jeecg.emp.vo.*;
import org.jeecg.emp.vo.DepartVo;
import org.jeecg.emp.vo.EmpInfoVo;
import org.jeecg.emp.vo.UserInfoVo;
import org.jeecg.user.entity.SysUser; import org.jeecg.user.entity.SysUser;
import java.util.List; import java.util.List;
@@ -109,4 +107,8 @@ public interface CqBaseEmployeeMapper extends BaseMapper<CqBaseEmployee> {
EmpInfoVo getEmpInfoVoByUserId(String userId); EmpInfoVo getEmpInfoVoByUserId(String userId);
IPage<StUserBalanceVo> getUserBalanceList(@Param("page") Page<StUserBalanceVo> page, @Param("timestamp") Long timestamp);
List<StUserBalanceVo> getUserBalanceList(@Param("timestamp") Long timestamp);
} }
@@ -95,6 +95,7 @@
NULL AS emp_sysno, -- 对应字段在 sys_user_sub 中不存在,填 NULL NULL AS emp_sysno, -- 对应字段在 sys_user_sub 中不存在,填 NULL
sus.birthday AS emp_birthday, sus.birthday AS emp_birthday,
CONCAT(LEFT(sus.card_no, 3), '*************', RIGHT(sus.card_no, 2)) AS emp_idcard, CONCAT(LEFT(sus.card_no, 3), '*************', RIGHT(sus.card_no, 2)) AS emp_idcard,
sus.card_no,
NULL AS emp_job, -- 对应字段在 sys_user_sub 中不存在,填 NULL NULL AS emp_job, -- 对应字段在 sys_user_sub 中不存在,填 NULL
NULL AS emp_group, NULL AS emp_group,
NULL AS emp_position, NULL AS emp_position,
@@ -130,6 +131,7 @@
sus.work_no, sus.work_no,
sus.sex, sus.sex,
CONCAT(LEFT(sus.phone, 3), '****', RIGHT(sus.phone, 4)) AS phone, CONCAT(LEFT(sus.phone, 3), '****', RIGHT(sus.phone, 4)) AS phone,
sus.phone phoneNum,
sus.create_time, sus.create_time,
sus.user_type, sus.user_type,
sus.main_user_id, sus.main_user_id,
@@ -187,6 +189,7 @@
NULL AS emp_sysno, -- 对应字段在 sys_user_sub 中不存在,填 NULL NULL AS emp_sysno, -- 对应字段在 sys_user_sub 中不存在,填 NULL
sus.birthday AS emp_birthday, sus.birthday AS emp_birthday,
CONCAT(LEFT(sus.card_no, 3), '*************', RIGHT(sus.card_no, 2)) AS emp_idcard, CONCAT(LEFT(sus.card_no, 3), '*************', RIGHT(sus.card_no, 2)) AS emp_idcard,
sus.card_no,
NULL AS emp_job, -- 对应字段在 sys_user_sub 中不存在,填 NULL NULL AS emp_job, -- 对应字段在 sys_user_sub 中不存在,填 NULL
NULL AS emp_group, NULL AS emp_group,
NULL AS emp_position, NULL AS emp_position,
@@ -208,15 +211,20 @@
NULL AS work_strength, NULL AS work_strength,
sus.del_flag, sus.del_flag,
sus.is_sync, sus.is_sync,
NULL AS secondDepartName, -- 对应字段在 sys_user_sub 中不存在,填 NULL parent_depart.depart_name AS secondDepartName,
NULL AS thirdDepartName, direct_depart.depart_name AS thirdDepartName,
NULL AS dep_id, CONCAT(
NULL AS depart_name, IFNULL(parent_depart.depart_name, ''),
IF(parent_depart.depart_name IS NOT NULL AND direct_depart.depart_name IS NOT NULL, '->', ''),
IFNULL(direct_depart.depart_name, '')
) AS departNames,
sus.depart_ids as departIds,
sus.username, sus.username,
sus.realname, sus.realname,
sus.avatar, sus.avatar,
sus.sex, sus.sex,
CONCAT(LEFT(sus.phone, 3), '****', RIGHT(sus.phone, 4)) AS phone, CONCAT(LEFT(sus.phone, 3), '****', RIGHT(sus.phone, 4)) AS phone,
sus.phone phoneNum,
sus.create_time, sus.create_time,
sus.user_type, sus.user_type,
sus.main_user_id, sus.main_user_id,
@@ -225,6 +233,12 @@
sus.status sus.status
FROM FROM
sys_user_sub sus sys_user_sub sus
LEFT JOIN sys_pay_depart direct_depart
ON sus.depart_ids = direct_depart.id
AND direct_depart.del_flag = '0'
LEFT JOIN sys_pay_depart parent_depart
ON direct_depart.parent_id = parent_depart.id
AND parent_depart.del_flag = '0'
WHERE 1 = 1 WHERE 1 = 1
AND sus.user_identity = 6 -- 根据需求过滤条件 AND sus.user_identity = 6 -- 根据需求过滤条件
AND sus.del_flag = 0 AND sus.del_flag = 0
@@ -274,6 +288,27 @@
</if> </if>
</select> </select>
<!-- 查询子用户 -->
<select id="selectChildrenByParentId" resultMap="userTreeResultMap">
SELECT *
FROM sys_user_sub
WHERE main_user_id = #{parentId}
and del_flag = 0
<if test="realname != null and realname != ''">
AND realname LIKE CONCAT('%', #{realname}, '%')
</if>
<if test="phone != null and phone != ''">
AND phone LIKE CONCAT('%', #{phone}, '%')
</if>
<if test="mainUserRelation != null and mainUserRelation != ''">
AND main_user_relation = #{mainUserRelation}
</if>
<if test="userType != null and userType != ''">
AND user_type = #{userType}
</if>
</select>
<update id="updateIsStatusByMemberId" parameterType="map"> <update id="updateIsStatusByMemberId" parameterType="map">
UPDATE st_client_member_balance UPDATE st_client_member_balance
<set> <set>
@@ -485,4 +520,75 @@
AND u.del_flag = 0 AND u.del_flag = 0
limit 1 limit 1
</select> </select>
<select id="getUserBalanceList" resultType="org.jeecg.emp.vo.StUserBalanceVo">
<!-- SELECT-->
<!-- us.id,-->
<!-- us.realname,-->
<!-- us.card_code,-->
<!-- us.card_code_status,-->
<!-- IF(us.card_code_status = 1,'正常',IF(us.card_code_status = 2, '挂失','未绑定/已解绑')) card_code_status_name,-->
<!-- us.phone,-->
<!-- us.work_no,-->
<!-- us.card_no,-->
<!-- us.depart_ids,-->
<!-- us.user_type,-->
<!-- us.canteen_id,-->
<!-- us.main_user_id,-->
<!-- IFNULL(( mb.top_up_balance + mb.reward_balance ),0) balance-->
<!-- FROM-->
<!-- sys_user_sub us-->
<!-- <if test="timestamp == null">-->
<!-- left join st_client_member_balance mb ON us.id = mb.member_id-->
<!-- </if>-->
<!-- <if test="timestamp != null and timestamp !='' ">-->
<!-- join st_client_member_balance mb ON us.id = mb.member_id-->
<!-- AND (mb.create_time > FROM_UNIXTIME(#{timestamp} / 1000)-->
<!-- or us.update_time > FROM_UNIXTIME(#{timestamp} / 1000)-->
<!-- or us.create_time > FROM_UNIXTIME(#{timestamp} / 1000)-->
<!-- or mb.update_time > FROM_UNIXTIME(#{timestamp} / 1000)-->
<!-- or mb.last_consumption_time > FROM_UNIXTIME(#{timestamp} / 1000))-->
<!-- </if>-->
SELECT
us.id,
us.realname,
us.card_code,
us.card_code_status,
IF(us.card_code_status = 1,'正常',IF(us.card_code_status = 2, '挂失','未绑定/已解绑')) card_code_status_name,
us.phone,
us.work_no,
us.card_no,
us.depart_ids,
us.user_type,
us.canteen_id,
us.main_user_id,
IFNULL(( mb.top_up_balance + mb.reward_balance ),0) balance
FROM
sys_user_sub us
<if test="timestamp == 0">
LEFT JOIN st_client_member_balance mb ON us.id = mb.member_id
</if>
<if test="timestamp > 0">
LEFT JOIN (
SELECT
member_id,
top_up_balance,
reward_balance
FROM st_client_member_balance
WHERE member_id IN (SELECT id FROM sys_user_sub WHERE update_time > FROM_UNIXTIME(#{timestamp}/1000))
OR
create_time > FROM_UNIXTIME(#{timestamp} / 1000)
OR update_time > FROM_UNIXTIME(#{timestamp} / 1000)
OR last_consumption_time > FROM_UNIXTIME(#{timestamp} / 1000)
) mb ON us.id = mb.member_id
</if>
WHERE 1=1
<if test="timestamp > 0">
AND (
us.update_time > FROM_UNIXTIME(#{timestamp} / 1000)
OR us.create_time > FROM_UNIXTIME(#{timestamp} / 1000)
OR mb.member_id IS NOT NULL
)
</if>
</select>
</mapper> </mapper>
@@ -1,11 +1,13 @@
package org.jeecg.emp.service; package org.jeecg.emp.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.emp.entity.CqBaseEmployee; import org.jeecg.emp.entity.CqBaseEmployee;
import org.jeecg.emp.vo.CqBaseEmpVo; import org.jeecg.emp.vo.CqBaseEmpVo;
import org.jeecg.emp.vo.DepartVo; import org.jeecg.emp.vo.DepartVo;
import org.jeecg.emp.vo.StUserBalanceVo;
import org.jeecg.user.entity.SysUser; import org.jeecg.user.entity.SysUser;
import org.jeecg.user.entity.SysUserSub; import org.jeecg.user.entity.SysUserSub;
import org.jeecg.user.vo.SysUserSubVo; import org.jeecg.user.vo.SysUserSubVo;
@@ -26,6 +28,8 @@ public interface ICqBaseEmployeeService extends IService<CqBaseEmployee> {
Page<CqBaseEmpVo> queryListV3(Page<CqBaseEmpVo> pageList, CqBaseEmpVo baseEmpVo); Page<CqBaseEmpVo> queryListV3(Page<CqBaseEmpVo> pageList, CqBaseEmpVo baseEmpVo);
Result<?> updateMainUserSubInfo(SysUserSub jsonObject);
Result<?> updateEmpSub(SysUserSub jsonObject); Result<?> updateEmpSub(SysUserSub jsonObject);
Result<?> cancellationAndRecovery(SysUserSubVo sysUserSub); Result<?> cancellationAndRecovery(SysUserSubVo sysUserSub);
@@ -38,4 +42,7 @@ public interface ICqBaseEmployeeService extends IService<CqBaseEmployee> {
public List<DepartVo> getSecondDepartList(); public List<DepartVo> getSecondDepartList();
List<SysUser> getUserList(List<String> idCardList); List<SysUser> getUserList(List<String> idCardList);
IPage<StUserBalanceVo> getUserBalanceList(Integer pageNo, Integer pageSize, Long timestamp);
List<StUserBalanceVo> getUserBalanceList(Long timestamp);
} }
@@ -1,5 +1,7 @@
package org.jeecg.emp.service.impl; package org.jeecg.emp.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -12,6 +14,9 @@ import org.jeecg.emp.mapper.CqBaseEmployeeMapper;
import org.jeecg.emp.service.ICqBaseEmployeeService; import org.jeecg.emp.service.ICqBaseEmployeeService;
import org.jeecg.emp.vo.CqBaseEmpVo; import org.jeecg.emp.vo.CqBaseEmpVo;
import org.jeecg.emp.vo.DepartVo; import org.jeecg.emp.vo.DepartVo;
import org.jeecg.emp.vo.StUserBalanceVo;
import org.jeecg.payment.entity.StClientMemberBalance;
import org.jeecg.payment.service.IStClientMemberBalanceService;
import org.jeecg.system.service.ISysPayDepartService; import org.jeecg.system.service.ISysPayDepartService;
import org.jeecg.system.service.ISysUserService; import org.jeecg.system.service.ISysUserService;
import org.jeecg.system.service.ISysUserSubService; import org.jeecg.system.service.ISysUserSubService;
@@ -49,6 +54,8 @@ public class CqBaseEmployeeServiceImpl extends ServiceImpl<CqBaseEmployeeMapper,
@Resource @Resource
private ISysPayDepartService iSysPayDepartService; private ISysPayDepartService iSysPayDepartService;
@Resource
private IStClientMemberBalanceService iStClientMemberBalanceService;
@Override @Override
@@ -115,6 +122,33 @@ public class CqBaseEmployeeServiceImpl extends ServiceImpl<CqBaseEmployeeMapper,
return page.setRecords(list); return page.setRecords(list);
} }
@Override
public Result<?> updateMainUserSubInfo(SysUserSub jsonObject){
Result<?> result = new Result<SysUserSub>();
try {
//更新用户表
SysUserSub sysUser = sysUserSubService.getById(jsonObject.getId());
//判断用户类型是否有更新 0: 正式员工 1:非正式员工,2:家庭用户
if(!sysUser.getUserType().equals(jsonObject.getUserType())){
if(2 != jsonObject.getUserType()){
//更新用户钱包
LambdaUpdateWrapper<StClientMemberBalance> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(StClientMemberBalance::getMemberId, sysUser.getId());
updateWrapper.set(StClientMemberBalance::getUserInnerType, jsonObject.getUserType());
iStClientMemberBalanceService.update(updateWrapper);
}
}
BeanUtils.copyProperties(jsonObject, sysUser);
sysUser.setUpdateTime(new Date());//设置创建时间
sysUserService.editUserSub(sysUser);
result.success("编辑成功!");
} catch (Exception e) {
log.error(e.getMessage(), e);
result.error500("操作失败");
}
return result;
}
@Override @Override
public Result<?> updateEmpSub(SysUserSub jsonObject) { public Result<?> updateEmpSub(SysUserSub jsonObject) {
Result<?> result = new Result<SysUserSub>(); Result<?> result = new Result<SysUserSub>();
@@ -176,4 +210,17 @@ public class CqBaseEmployeeServiceImpl extends ServiceImpl<CqBaseEmployeeMapper,
public List<SysUser> getUserList(List<String> idCardList) { public List<SysUser> getUserList(List<String> idCardList) {
return baseMapper.getUserList(idCardList); return baseMapper.getUserList(idCardList);
} }
//分页获取用户余额信息
@Override
public IPage<StUserBalanceVo> getUserBalanceList(Integer pageNo, Integer pageSize, Long timestamp){
Page<StUserBalanceVo> page = new Page<>(pageNo,pageSize);
return baseMapper.getUserBalanceList(page, timestamp);
}
@Override
public List<StUserBalanceVo> getUserBalanceList(Long timestamp){
System.out.println("用户余额心跳 :"+timestamp);
return baseMapper.getUserBalanceList(timestamp);
}
} }
@@ -1,24 +0,0 @@
package org.jeecg.equipment.controller;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.equipment.entity.StEquipment;
import org.jeecg.equipment.service.IStEquipmentService;
import org.springframework.web.bind.annotation.*;
/**
* @Description: 设备管理表
* @Author: jeecg-boot
* @Date: 2022-08-30
* @Version: V1.0
*/
@Tag(name="设备管理表")
@RestController
@RequestMapping("/equipment/stEquipment")
@Slf4j
public class StEquipmentController extends JeecgController<StEquipment, IStEquipmentService> {
}
@@ -1,18 +1,26 @@
package org.jeecg.equipment.controller; package org.jeecg.equipment.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.equipment.dto.StEquipmentDto;
import org.jeecg.equipment.entity.StEquipment; import org.jeecg.equipment.entity.StEquipment;
import org.jeecg.equipment.service.IStCanteenEquipmentService;
import org.jeecg.equipment.service.IStEquipmentService; import org.jeecg.equipment.service.IStEquipmentService;
import org.jeecg.payment.vo.StCanteenEquipmentVo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List; import java.util.List;
/** /**
@@ -25,9 +33,13 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/restaurant/equipment/stEquipment") @RequestMapping("/restaurant/equipment/stEquipment")
@Slf4j @Slf4j
public class StRestaurantEquipmentController extends JeecgController<StEquipment, IStEquipmentService> { public class StRestaurantEquipmentController {
@Autowired @Autowired
private IStEquipmentService stEquipmentService; private IStEquipmentService stEquipmentService;
@Resource
private IStCanteenEquipmentService stCanteenEquipmentService;
@Resource
private RedisUtil redisUtil;
/** /**
@@ -52,4 +64,65 @@ public class StRestaurantEquipmentController extends JeecgController<StEquipment
return Result.OK(token); return Result.OK(token);
} }
/**
* 获取设备列表根据食堂id
*/
@Operation(summary = "获取设备列表根据食堂id", description = "获取设备列表根据食堂id")
@GetMapping("/getEquipmentListByCanteenId")
@AutoLog(value = "获取设备列表根据食堂id")
public Result<List<StEquipment>> getEquipmentListByCanteenId(@RequestParam(name = "canteenId", required = true) String canteenId) {
if(StringUtils.isBlank(canteenId)){
return Result.error("参数异常");
}
List<StEquipment> stEquipmentList = stEquipmentService.getEquipmentList(canteenId);
return Result.OK(stEquipmentList);
}
/**
* 保存设备
* @param dto 设备信息
* @return 保存结果
*/
@Operation(summary = "保存设备", description = "保存设备")
@PostMapping("/saveEquipment")
@AutoLog(value = "保存设备")
public Result<String> saveEquipment(@RequestBody StEquipmentDto dto) {
if(StringUtils.isBlank(dto.getAppPackageLocalUrl())){
return Result.error("设备编码不能为空");
}
LambdaUpdateWrapper<StEquipment> stEquipmentLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
stEquipmentLambdaUpdateWrapper
.eq(StEquipment::getAppPackageLocalUrl, dto.getAppPackageLocalUrl())
.set(StEquipment::getPlacement, dto.getPlacement())
.set(StEquipment::getRemark, dto.getRemark());
stEquipmentService.update(stEquipmentLambdaUpdateWrapper);
return Result.OK("操作成功");
}
/**
* 设备管理列表
* @param canteenId 食堂id
* @param appPackageLocalUrl 设备编码
* @param pageNo 页码
* @param pageSize 每页条数
* @return 设备管理列表
*/
@Operation(summary = "设备管理列表", description = "设备管理列表")
@GetMapping("/pageList")
@AutoLog(value = "设备管理列表")
public Result<IPage<StCanteenEquipmentVo>> pageList(@RequestParam(name = "canteenId",required = false) String canteenId,
@RequestParam(name = "appPackageLocalUrl",required = false) String appPackageLocalUrl,
@RequestParam(name = "pageNo",required = false,defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize",required = false,defaultValue = "10") Integer pageSize){
return Result.OK(stCanteenEquipmentService.pageList(canteenId,appPackageLocalUrl,pageNo,pageSize));
}
@Operation(summary = "下发用户信息", description = "下发用户信息")
@GetMapping("/issueInformation")
@AutoLog(value = "下发用户信息")
public Result<String> issueInformation(@RequestParam(name = "equipmentCode") String equipmentCode){
redisUtil.hset(CommonConstant.ISSUE_INFORMATION,equipmentCode,"1");
return Result.OK("命令发送成功");
}
} }
@@ -0,0 +1,23 @@
package org.jeecg.equipment.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.jeecg.equipment.entity.StCanteenEquipment;
import org.jeecg.payment.vo.StCanteenEquipmentVo;
import org.jeecg.payment.vo.StRecordNumVo;
import java.util.List;
public interface StCanteenEquipmentMapper extends BaseMapper<StCanteenEquipment> {
IPage<StCanteenEquipmentVo> pageList(@Param("page") Page<StCanteenEquipmentVo> page, @Param("canteenId") String canteenId,@Param("appPackageLocalUrl") String appPackageLocalUrl);
List<StRecordNumVo> getNormalNum(@Param("list") List<String> deviceCodes);
List<StRecordNumVo> getAbnormalNum(@Param("list") List<String> deviceCodes);
}
@@ -1,8 +1,11 @@
package org.jeecg.equipment.mapper; package org.jeecg.equipment.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.jeecg.equipment.entity.StEquipment; import org.jeecg.equipment.entity.StEquipment;
import java.util.List;
/** /**
* @Description: 设备管理表 * @Description: 设备管理表
* @Author: jeecg-boot * @Author: jeecg-boot
@@ -11,4 +14,5 @@ import org.jeecg.equipment.entity.StEquipment;
*/ */
public interface StEquipmentMapper extends BaseMapper<StEquipment> { public interface StEquipmentMapper extends BaseMapper<StEquipment> {
List<StEquipment> getEquipmentList(@Param("canteenId") String canteenId);
} }
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.equipment.mapper.StCanteenEquipmentMapper">
<select id="pageList" resultType="org.jeecg.payment.vo.StCanteenEquipmentVo">
SELECT
r.id canteen_id,
r.rest_name,
e.equipment_name,
e.equipment_code,
e.app_package_local_url,
e.placement,
e.remark,
ce.equipment_ip,
ce.face_num,
ce.available_memory
FROM
st_base_restaurant r
LEFT JOIN st_equipment e ON r.rest_no = e.canteen_id
LEFT JOIN st_canteen_equipment ce ON ce.equipment_code = e.equipment_code
WHERE e.equipment_name = 'com.sw.billing'
<if test="canteenId != null and canteenId != ''">
AND r.id = #{canteenId}
</if>
<if test="appPackageLocalUrl != null and appPackageLocalUrl != ''">
AND e.app_package_local_url LIKE CONCAT(CONCAT('%', #{appPackageLocalUrl}), '%')
</if>
</select>
<select id="getNormalNum" resultType="org.jeecg.payment.vo.StRecordNumVo">
SELECT
r.device_code,
COUNT(r.id) num
FROM
st_client_member_transaction_record r
WHERE
r.`status` = 101
AND r.device_code IN
<foreach item="item" collection="list" separator="," open="(" close=")">
#{item}
</foreach>
GROUP BY r.device_code
</select>
<select id="getAbnormalNum" resultType="org.jeecg.payment.vo.StRecordNumVo">
SELECT
r.device_code,
COUNT(r.id) num
FROM
st_consumption_exception_record r
WHERE
r.device_code IN
<foreach item="item" collection="list" separator="," open="(" close=")">
#{item}
</foreach>
GROUP BY r.device_code
</select>
</mapper>
@@ -2,4 +2,13 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.equipment.mapper.StEquipmentMapper"> <mapper namespace="org.jeecg.equipment.mapper.StEquipmentMapper">
<select id="getEquipmentList" resultType="org.jeecg.equipment.entity.StEquipment">
SELECT
e.*
FROM
st_equipment e
LEFT JOIN st_base_restaurant r ON e.canteen_id = r.rest_no
WHERE
r.id = #{canteenId}
</select>
</mapper> </mapper>
@@ -0,0 +1,16 @@
package org.jeecg.equipment.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.equipment.entity.StCanteenEquipment;
import org.jeecg.equipment.entity.StEquipment;
import org.jeecg.payment.vo.StCanteenEquipmentVo;
import java.util.List;
public interface IStCanteenEquipmentService extends IService<StCanteenEquipment> {
IPage<StCanteenEquipmentVo> pageList(String canteenId, String appPackageLocalUrl, Integer pageNo, Integer pageSize);
}
@@ -3,6 +3,8 @@ package org.jeecg.equipment.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.equipment.entity.StEquipment; import org.jeecg.equipment.entity.StEquipment;
import java.util.List;
/** /**
* @Description: 设备管理表 * @Description: 设备管理表
* @Author: jeecg-boot * @Author: jeecg-boot
@@ -11,4 +13,5 @@ import org.jeecg.equipment.entity.StEquipment;
*/ */
public interface IStEquipmentService extends IService<StEquipment> { public interface IStEquipmentService extends IService<StEquipment> {
List<StEquipment> getEquipmentList(String canteenId);
} }
@@ -0,0 +1,64 @@
package org.jeecg.equipment.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.equipment.entity.StCanteenEquipment;
import org.jeecg.equipment.mapper.StCanteenEquipmentMapper;
import org.jeecg.equipment.service.IStCanteenEquipmentService;
import org.jeecg.payment.vo.StCanteenEquipmentVo;
import org.jeecg.payment.vo.StRecordNumVo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class StCanteenEquipmentServiceImpl extends ServiceImpl<StCanteenEquipmentMapper, StCanteenEquipment> implements IStCanteenEquipmentService {
@Resource
private RedisUtil redisUtil;
@Override
public IPage<StCanteenEquipmentVo> pageList(String canteenId,String appPackageLocalUrl,Integer pageNo,Integer pageSize){
Page<StCanteenEquipmentVo> page = new Page<>(pageNo, pageSize);
IPage<StCanteenEquipmentVo> stCanteenEquipmentVoIPage = baseMapper.pageList(page, canteenId, appPackageLocalUrl);
if(CollectionUtils.isNotEmpty(stCanteenEquipmentVoIPage.getRecords())){
List<String> collect = stCanteenEquipmentVoIPage.getRecords().stream().map(StCanteenEquipmentVo::getEquipmentCode).collect(Collectors.toList());
List<StRecordNumVo> normalNum = baseMapper.getNormalNum(collect);
List<StRecordNumVo> abnormalNum = baseMapper.getAbnormalNum(collect);
Map<String, Integer> normalNumMap = normalNum.stream().collect(Collectors.toMap(StRecordNumVo::getDeviceCode, StRecordNumVo::getNum));
Map<String, Integer> abnormalNumMap = abnormalNum.stream().collect(Collectors.toMap(StRecordNumVo::getDeviceCode,StRecordNumVo::getNum));
Map<Object, Object> hmget = redisUtil.hmget(CommonConstant.DEVICE_STATUS);
long oneMinuteMs = 2 * 60 * 1000;
stCanteenEquipmentVoIPage.getRecords().forEach(equipment ->{
//设备上传数据量
Integer a = normalNumMap.get(equipment.getEquipmentCode()) == null ? 0 : normalNumMap.get(equipment.getEquipmentCode());
Integer b = abnormalNumMap.get(equipment.getEquipmentCode()) == null ? 0 : abnormalNumMap.get(equipment.getEquipmentCode());
equipment.setTotalNum(a+b);
equipment.setStatus("离线");
//设备状态
Object o = hmget.get(equipment.getEquipmentCode());
if(o != null){
//对比设备心跳时间与当前时间, 如果时间差小于2分钟 , 视为在线
long deviceTime = Long.parseLong((String) o);
long now = new Date().getTime();
if(now - deviceTime < oneMinuteMs){
equipment.setStatus("在线");
}
}
});
}
return stCanteenEquipmentVoIPage;
}
}
@@ -1,5 +1,6 @@
package org.jeecg.equipment.service.impl; package org.jeecg.equipment.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.jeecg.equipment.entity.StEquipment; import org.jeecg.equipment.entity.StEquipment;
import org.jeecg.equipment.mapper.StEquipmentMapper; import org.jeecg.equipment.mapper.StEquipmentMapper;
import org.jeecg.equipment.service.IStEquipmentService; import org.jeecg.equipment.service.IStEquipmentService;
@@ -7,6 +8,8 @@ import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.List;
/** /**
* @Description: 设备管理表 * @Description: 设备管理表
* @Author: jeecg-boot * @Author: jeecg-boot
@@ -16,4 +19,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@Service @Service
public class StEquipmentServiceImpl extends ServiceImpl<StEquipmentMapper, StEquipment> implements IStEquipmentService { public class StEquipmentServiceImpl extends ServiceImpl<StEquipmentMapper, StEquipment> implements IStEquipmentService {
@Override
public List<StEquipment> getEquipmentList(String canteenId) {
return baseMapper.getEquipmentList(canteenId);
}
} }
@@ -3,6 +3,7 @@ package org.jeecg.pay.controller;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -12,6 +13,8 @@ import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.RedisUtil; import org.jeecg.common.util.RedisUtil;
import org.jeecg.emp.service.ICqBaseEmployeeService;
import org.jeecg.emp.vo.StUserBalanceVo;
import org.jeecg.equipment.entity.StEquipment; import org.jeecg.equipment.entity.StEquipment;
import org.jeecg.equipment.service.IStEquipmentService; import org.jeecg.equipment.service.IStEquipmentService;
import org.jeecg.payment.entity.StBbzxOrderInfo; import org.jeecg.payment.entity.StBbzxOrderInfo;
@@ -39,7 +42,7 @@ import java.util.concurrent.CompletableFuture;
*/ */
@Tag(name = "0.食堂API接口支付相关 ") @Tag(name = "0.食堂API接口支付相关 ")
@RestController @RestController
@RequestMapping("/zhstapi/pay/") @RequestMapping("/zhstapi/pay")
@Slf4j @Slf4j
public class StPayController { public class StPayController {
// @Autowired // @Autowired
@@ -59,6 +62,8 @@ public class StPayController {
@Resource @Resource
private ISlBaseDinnerTimeService slBaseDinnerTimeService; private ISlBaseDinnerTimeService slBaseDinnerTimeService;
@Resource
private ICqBaseEmployeeService cqBaseEmployeeService;
/** /**
* 根据设备号获取token * 根据设备号获取token
@@ -75,20 +80,6 @@ public class StPayController {
if(CollectionUtils.isEmpty(stEquipmentList)){ if(CollectionUtils.isEmpty(stEquipmentList)){
log.error("根据设备号获取token,异常:设备编号不存在,qrcodeId="+qrcodeId); log.error("根据设备号获取token,异常:设备编号不存在,qrcodeId="+qrcodeId);
return Result.error("设备编号不存在"); return Result.error("设备编号不存在");
} else {
// try {
// //查询设备编码
// StEquipment stEquipment = stEquipmentList.get(0);
// String canteenId = slBaseRestaurantService.getCanteenId(stEquipment.getCanteenId());
// SlBaseDinnerTime slBaseDinnerTime = stBaseService.getCanteenDinnerType(canteenId);
// if(null != slBaseDinnerTime && StringUtils.isNotBlank(slBaseDinnerTime.getDinnerType())){
// String timesName = slBaseDinnerTime.getDinnerType();
// //异步上传设备统计信息
// iStRfidDeviceLogService.syncUploadDeviceInfo(qrcodeId,canteenId,timesName,null,slBaseDinnerTime,null);
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
} }
} }
String token = JwtUtil.signUserId("0000000000000000001", qrcodeId, qrcodeId,"4"); String token = JwtUtil.signUserId("0000000000000000001", qrcodeId, qrcodeId,"4");
@@ -99,7 +90,7 @@ public class StPayController {
@Operation(summary = "", description = "提供根据食堂ID获取食堂配置信息") @Operation(summary = "", description = "提供根据食堂ID获取食堂配置信息")
@GetMapping(value = "/getDinnerType/byCanteenId") @GetMapping(value = "/getDinnerType/byCanteenId")
@AutoLog(value = "提供根据食堂ID获取食堂配置信息") @AutoLog(value = "提供根据食堂ID获取食堂配置信息")
public Result<?> getCanteenInfoByCanteenId(@RequestParam(name = "restId", required = true) String restId) { public Result<StClientMemberLevelDeductRuleVo> getCanteenInfoByCanteenId(@RequestParam(name = "restId", required = true) String restId) {
SlBaseRestaurant slBaseRestaurant = slBaseRestaurantService.getById(restId); SlBaseRestaurant slBaseRestaurant = slBaseRestaurantService.getById(restId);
if(null == slBaseRestaurant){ if(null == slBaseRestaurant){
return Result.error("食堂未找到,请检查参数"); return Result.error("食堂未找到,请检查参数");
@@ -109,10 +100,100 @@ public class StPayController {
if(null == levelDeductRuleVo || null == levelDeductRuleVo.getDeductionType()){ if(null == levelDeductRuleVo || null == levelDeductRuleVo.getDeductionType()){
return Result.error("食堂未设置扣费规则"); return Result.error("食堂未设置扣费规则");
} }
List<SlBaseDinnerTime> list = slBaseDinnerTimeService.list(new LambdaQueryWrapper<SlBaseDinnerTime>().eq(SlBaseDinnerTime::getRestId, restId));
levelDeductRuleVo.setDinnerTimes(list);
levelDeductRuleVo.setIsOverdraftDine(slBaseRestaurant.getIsOverdraftDine()); levelDeductRuleVo.setIsOverdraftDine(slBaseRestaurant.getIsOverdraftDine());
levelDeductRuleVo.setIsExternalDineFlag(slBaseRestaurant.getIsExternalDine()); levelDeductRuleVo.setIsExternalDineFlag(slBaseRestaurant.getIsExternalDine());
return Result.OK(levelDeductRuleVo); return Result.OK(levelDeductRuleVo);
} }
@Operation(summary = "获取用户类型,余额信息", description = "获取用户类型,余额信息")
@GetMapping(value = "/getUserBalanceList")
@AutoLog(value = "获取用户类型,余额信息")
public Result<?> getUserBalanceList(@RequestParam(name = "pageNo", required = false) Integer pageNo,
@RequestParam(name = "pageSize", required = false) Integer pageSize,
@RequestParam(name = "timestamp", required = false, defaultValue = "0") Long timestamp){
if(null == pageNo || pageSize == 0){
log.error("getUserBalanceList 用户信息,分页调用全量数据");
return Result.OK(cqBaseEmployeeService.getUserBalanceList(timestamp));
}else {
log.error("getUserBalanceList 用户信息心跳 时间戳,timestamp={},date = {}", JSONObject.toJSONString(timestamp), DateUtil.format(new Date(timestamp), "yyyy-MM-dd HH:mm:ss"));
return Result.OK(cqBaseEmployeeService.getUserBalanceList(pageNo, pageSize, timestamp));
}
}
/**
* 离线人脸扣费v3 ,加自定义金额、卡号扣款
* @param stRfidoffLineVo
* @return
*/
@Operation(summary = "离线人脸扣费v3", description = "离线人脸扣费v2")
@PostMapping(value = "/payUser/offline/v3")
@AutoLog(value = "离线人脸扣费v3")
public Result<StClientMemberSpendVO> bindUserOfflineV3(@RequestBody StRfidoffLineVo stRfidoffLineVo) {
return iStClientMemberLevelDeductRuleService.
bindUserOfflineCardCode(stRfidoffLineVo,false);
}
/**
* 在线扣费
* @return
*/
@Operation(summary = "在线扣费", description = "在线扣费")
@PostMapping(value = "/payUser/online")
@AutoLog(value = "在线扣费")
public Result<StClientMemberSpendVO> bindUserOnline(@RequestBody StRfidVo stRfidVo) {
StRfidoffLineVo stRfidoffLineVo = new StRfidoffLineVo();
stRfidoffLineVo.setDeviceCode(stRfidVo.getDeviceCode());
stRfidoffLineVo.setVoList(Collections.singletonList(stRfidVo));
stRfidoffLineVo.setRestId(stRfidVo.getRestId());
return iStClientMemberLevelDeductRuleService.bindUserOfflineCardCode(stRfidoffLineVo,true);
}
@@ -238,34 +319,6 @@ public class StPayController {
return Result.OK("扣费成功"); return Result.OK("扣费成功");
} }
/**
* 离线人脸扣费v3 ,加自定义金额、卡号扣款
* @param stRfidoffLineVo
* @return
*/
@Operation(summary = "离线人脸扣费v3", description = "离线人脸扣费v2")
@PostMapping(value = "/payUser/offline/v3")
@AutoLog(value = "离线人脸扣费v3")
public Result<StClientMemberSpendVO> bindUserOfflineV3(@RequestBody StRfidoffLineVo stRfidoffLineVo) {
return iStClientMemberLevelDeductRuleService.bindUserOfflineCardCode(stRfidoffLineVo);
}
/**
* 在线扣费
* @return
*/
@Operation(summary = "在线扣费", description = "在线扣费")
@PostMapping(value = "/payUser/online")
@AutoLog(value = "在线扣费")
public Result<StClientMemberSpendVO> bindUserOnline(@RequestBody StRfidVo stRfidVo) {
StRfidoffLineVo stRfidoffLineVo = new StRfidoffLineVo();
stRfidoffLineVo.setDeviceCode(stRfidVo.getDeviceCode());
stRfidoffLineVo.setVoList(Collections.singletonList(stRfidVo));
stRfidoffLineVo.setRestId(stRfidVo.getRestId());
return iStClientMemberLevelDeductRuleService.bindUserOfflineCardCode(stRfidoffLineVo);
}
/** /**
@@ -13,6 +13,7 @@ import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.ScreenVo;
import org.jeecg.payment.dto.StAmountSpentEveryMemberDTO; import org.jeecg.payment.dto.StAmountSpentEveryMemberDTO;
import org.jeecg.payment.dto.StClientMemberTransactionRecordDTO; import org.jeecg.payment.dto.StClientMemberTransactionRecordDTO;
import org.jeecg.payment.service.IStBbzxOrderInfoService; import org.jeecg.payment.service.IStBbzxOrderInfoService;
@@ -26,7 +27,9 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* 订单 控制器 * 订单 控制器
@@ -91,7 +94,7 @@ public class StBbzxOrderInfoController {
sumResult.setRestName("总计"); sumResult.setRestName("总计");
sumResult.setEatDay(startDate+"~"+endDate); sumResult.setEatDay(startDate+"~"+endDate);
statisticsTheAmountSpentList.add(sumResult); statisticsTheAmountSpentList.add(sumResult);
String exportFields = "restName|食堂名称,customerPrice|消费总额(元),totalCount|消费人次,totalNum|消费人数," + String exportFields = "restName|食堂名称,totalCount|消费人次,customerPrice|消费总额(元),totalNum|消费人数," +
"breakfastAmount|早餐消费金额(元),breakfastPerson|早餐消费次数,lunchAmount|午餐消费金额(元),lunchPerson|午餐消费次数,dinnerAmount|晚餐消费金额(元),dinnerPerson|晚餐消费次数" + "breakfastAmount|早餐消费金额(元),breakfastPerson|早餐消费次数,lunchAmount|午餐消费金额(元),lunchPerson|午餐消费次数,dinnerAmount|晚餐消费金额(元),dinnerPerson|晚餐消费次数" +
",otherAmount|其他消费金额(元),otherPerson|其他消费次数,orderPrice|结算金额(元),eatDay|消费日期"; ",otherAmount|其他消费金额(元),otherPerson|其他消费次数,orderPrice|结算金额(元),eatDay|消费日期";
ExcelUtils.export(response, "食堂消费统计", statisticsTheAmountSpentList, exportFields, "yyyy-MM-dd HH:mm",true); ExcelUtils.export(response, "食堂消费统计", statisticsTheAmountSpentList, exportFields, "yyyy-MM-dd HH:mm",true);
@@ -184,7 +187,7 @@ public class StBbzxOrderInfoController {
sumResult.setDepartName(null); sumResult.setDepartName(null);
sumResult.setEatDay(startDate+"~"+endDate); sumResult.setEatDay(startDate+"~"+endDate);
statisticsTheAmountSpentList.add(sumResult); statisticsTheAmountSpentList.add(sumResult);
String exportFields = "realname|姓名,customerPrice|消费总额(元),workNo|工号,departName|部门,totalCount|消费次数,totalNum|消费天数," + String exportFields = "workNo|工号,realname|姓名,departName|部门,totalCount|消费次数,customerPrice|消费总额(元),restName|食堂名称,totalNum|消费天数," +
"breakfastAmount|早餐消费金额(元),breakfastPerson|早餐消费次数,lunchAmount|午餐消费金额(元),lunchPerson|午餐消费次数,dinnerAmount|晚餐消费金额(元),dinnerPerson|晚餐消费次数" + "breakfastAmount|早餐消费金额(元),breakfastPerson|早餐消费次数,lunchAmount|午餐消费金额(元),lunchPerson|午餐消费次数,dinnerAmount|晚餐消费金额(元),dinnerPerson|晚餐消费次数" +
",otherAmount|其他消费金额(元),otherPerson|其他消费次数,orderPrice|结算金额(元),eatDay|消费日期"; ",otherAmount|其他消费金额(元),otherPerson|其他消费次数,orderPrice|结算金额(元),eatDay|消费日期";
ExcelUtils.export(response, "个人消费统计", statisticsTheAmountSpentList, exportFields, "yyyy-MM-dd HH:mm",true); ExcelUtils.export(response, "个人消费统计", statisticsTheAmountSpentList, exportFields, "yyyy-MM-dd HH:mm",true);
@@ -292,20 +295,20 @@ public class StBbzxOrderInfoController {
query.setStartTime(query.getDates().get(0)); query.setStartTime(query.getDates().get(0));
query.setEndTime(query.getDates().get(1)); query.setEndTime(query.getDates().get(1));
} }
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); String canteenId = query.getCanteenId();
//餐品总库只查询内置食堂 List<String> canteenIdList = new ArrayList<>();
if(sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_0) || sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_1)){ if(StringUtils.isNotBlank(canteenId)){
// 后期分数据权限时在解开注释,此处管理员账户能看到所有食堂数据 canteenIdList.add(canteenId);
// ScreenVo screenVo = new ScreenVo();
// screenVo.setId(CommonConstant.INLAY_CANTEEN_ID);
// canteenIdList.add(screenVo);
} else if (sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_4)) {
//查询当前登录用户的食堂列表
String canteenId = sysUser.getCanteenId();
query.setCanteenId(canteenId);
} else { } else {
return Result.OK(); //权限校验
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<String> canteenIds = new ArrayList<>();
if(sysUser != null){
canteenIds = sysUser.getCanteenIdList().stream().map(ScreenVo::getId).collect(Collectors.toList());
canteenIdList.addAll(canteenIds);
} }
}
query.setCanteenIdList(canteenIdList);
query.setStatus(3);//(充值=102 query.setStatus(3);//(充值=102
return Result.OK(iStClientMemberTransactionRecordService.pageQuery(query)); return Result.OK(iStClientMemberTransactionRecordService.pageQuery(query));
} }
@@ -323,20 +326,20 @@ public class StBbzxOrderInfoController {
query.setStartTime(split[0]); query.setStartTime(split[0]);
query.setEndTime(split[1]); query.setEndTime(split[1]);
} }
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); String canteenId = query.getCanteenId();
//餐品总库只查询内置食堂 List<String> canteenIdList = new ArrayList<>();
if(sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_0) || sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_1)){ if(StringUtils.isNotBlank(canteenId)){
// 后期分数据权限时在解开注释,此处管理员账户能看到所有食堂数据 canteenIdList.add(canteenId);
// ScreenVo screenVo = new ScreenVo();
// screenVo.setId(CommonConstant.INLAY_CANTEEN_ID);
// canteenIdList.add(screenVo);
} else if (sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_4)) {
//查询当前登录用户的食堂列表
String canteenId = sysUser.getCanteenId();
query.setCanteenId(canteenId);
} else { } else {
return Result.OK(); //权限校验
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<String> canteenIds = new ArrayList<>();
if(sysUser != null){
canteenIds = sysUser.getCanteenIdList().stream().map(ScreenVo::getId).collect(Collectors.toList());
canteenIdList.addAll(canteenIds);
} }
}
query.setCanteenIdList(canteenIdList);
query.setStatus(3);//(充值=102 query.setStatus(3);//(充值=102
List<StClientMemberTransactionRecordVO> statisticsCanteenBusiness = iStClientMemberTransactionRecordService.queryList(query); List<StClientMemberTransactionRecordVO> statisticsCanteenBusiness = iStClientMemberTransactionRecordService.queryList(query);
StClientMemberTransactionRecordVO sumResult = GenericSumUtil.sumList(statisticsCanteenBusiness, StClientMemberTransactionRecordVO.class); StClientMemberTransactionRecordVO sumResult = GenericSumUtil.sumList(statisticsCanteenBusiness, StClientMemberTransactionRecordVO.class);
@@ -344,6 +347,7 @@ public class StBbzxOrderInfoController {
StClientMemberTransactionRecordVO stClientMemberTransactionRecordVO = new StClientMemberTransactionRecordVO();//只汇总交易金额 StClientMemberTransactionRecordVO stClientMemberTransactionRecordVO = new StClientMemberTransactionRecordVO();//只汇总交易金额
stClientMemberTransactionRecordVO.setSerialNo("总计"); stClientMemberTransactionRecordVO.setSerialNo("总计");
stClientMemberTransactionRecordVO.setTransactionAmount(sumResult.getTransactionAmount()); stClientMemberTransactionRecordVO.setTransactionAmount(sumResult.getTransactionAmount());
stClientMemberTransactionRecordVO.setAvailableBalance(sumResult.getAvailableBalance());
return Result.OK(stClientMemberTransactionRecordVO); return Result.OK(stClientMemberTransactionRecordVO);
} }
@@ -357,20 +361,20 @@ public class StBbzxOrderInfoController {
query.setStartTime(split[0]); query.setStartTime(split[0]);
query.setEndTime(split[1]); query.setEndTime(split[1]);
} }
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); String canteenId = query.getCanteenId();
//餐品总库只查询内置食堂 List<String> canteenIdList = new ArrayList<>();
if(sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_0) || sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_1)){ if(StringUtils.isNotBlank(canteenId)){
// 后期分数据权限时在解开注释,此处管理员账户能看到所有食堂数据 canteenIdList.add(canteenId);
// ScreenVo screenVo = new ScreenVo();
// screenVo.setId(CommonConstant.INLAY_CANTEEN_ID);
// canteenIdList.add(screenVo);
} else if (sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_4)) {
//查询当前登录用户的食堂列表
String canteenId = sysUser.getCanteenId();
query.setCanteenId(canteenId);
} else { } else {
return; //权限校验
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<String> canteenIds = new ArrayList<>();
if(sysUser != null){
canteenIds = sysUser.getCanteenIdList().stream().map(ScreenVo::getId).collect(Collectors.toList());
canteenIdList.addAll(canteenIds);
} }
}
query.setCanteenIdList(canteenIdList);
query.setStatus(3);//(充值=102 query.setStatus(3);//(充值=102
List<StClientMemberTransactionRecordVO> statisticsCanteenBusiness = iStClientMemberTransactionRecordService.queryList(query); List<StClientMemberTransactionRecordVO> statisticsCanteenBusiness = iStClientMemberTransactionRecordService.queryList(query);
if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(statisticsCanteenBusiness)){ if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(statisticsCanteenBusiness)){
@@ -383,9 +387,9 @@ public class StBbzxOrderInfoController {
// String exportFields = "serialNo|交易流水号,orderNo|交易单号,userName|姓名,phone|手机号,workNo|工号," + // String exportFields = "serialNo|交易流水号,orderNo|交易单号,userName|姓名,phone|手机号,workNo|工号," +
// "statusName|操作类型,transactionAmount|交易金额,paymentMethodName|结账方式,storedBalance|储值金额变动(元),rewardBalance|赠送金额变动(元),availableBalance|余额," + // "statusName|操作类型,transactionAmount|交易金额,paymentMethodName|结账方式,storedBalance|储值金额变动(元),rewardBalance|赠送金额变动(元),availableBalance|余额," +
// "integralBalance|积分变动,createTime|交易时间,payTime|结账时间,updateStatusName|操作端,createOne|操作人"; // "integralBalance|积分变动,createTime|交易时间,payTime|结账时间,updateStatusName|操作端,createOne|操作人";
String exportFields = "serialNo|交易流水号,orderNo|交易单号,userName|姓名,phone|手机号,workNo|工号," + String exportFields = "workNo|工号,userName|姓名,restName|充值食堂名称,transactionAmount|交易金额,statusName|操作类型," +
"transactionAmount|交易金额,statusName|操作类型,paymentMethodName|充值方式,availableBalance|现金余额," + "availableBalance|现金余额," +
"createTime|充值时间,createOne|操作人"; "createTime|充值时间,phone|手机号";
ExcelUtils.export(response, "充值记录", statisticsCanteenBusiness, exportFields, "yyyy-MM-dd HH:mm",true); ExcelUtils.export(response, "充值记录", statisticsCanteenBusiness, exportFields, "yyyy-MM-dd HH:mm",true);
} }
@@ -12,6 +12,7 @@ import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.ScreenVo;
import org.jeecg.payment.dto.StClientMemberChangeBalanceDTO; import org.jeecg.payment.dto.StClientMemberChangeBalanceDTO;
import org.jeecg.payment.dto.StClientMemberTopUpDTO; import org.jeecg.payment.dto.StClientMemberTopUpDTO;
import org.jeecg.payment.dto.StClientMemberTransactionRecordDTO; import org.jeecg.payment.dto.StClientMemberTransactionRecordDTO;
@@ -37,7 +38,6 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -115,16 +115,11 @@ public class StClientMemberBalanceController {
clientMemberWrapper.eq(StClientMemberBalance::getMemberId, userId); clientMemberWrapper.eq(StClientMemberBalance::getMemberId, userId);
StClientMemberBalance balance = iStClientMemberBalanceService.getOne(clientMemberWrapper); StClientMemberBalance balance = iStClientMemberBalanceService.getOne(clientMemberWrapper);
// Map<String, Object> map = iStClientMemberLevelDemotionTimeService.topUpAwardService(null, value.floatValue(),canteenId);
BigDecimal rewardBalance = new BigDecimal(0); BigDecimal rewardBalance = new BigDecimal(0);
int integralBalance = 0; int integralBalance = 0;
StClientMemberTopUpDTO query = new StClientMemberTopUpDTO(); StClientMemberTopUpDTO query = new StClientMemberTopUpDTO();
query.setId(balance.getId()); query.setId(balance.getId());
query.setCanteenId(canteenId); query.setCanteenId(canteenId);
// if(null != map){
// rewardBalance = BigDecimal.valueOf(Float.parseFloat(map.get("amount").toString()));
// integralBalance = Integer.parseInt(map.get("integral").toString());
// }
query.setTopUpBalance(value); query.setTopUpBalance(value);
query.setRewardBalance(rewardBalance); query.setRewardBalance(rewardBalance);
query.setIntegralBalance(integralBalance); query.setIntegralBalance(integralBalance);
@@ -399,6 +394,7 @@ public class StClientMemberBalanceController {
@PostMapping("/backOutTopUpAll") @PostMapping("/backOutTopUpAll")
@Operation(summary = "用户充值-撤销充值(线下线下二合一)", description = "流水表主键id") @Operation(summary = "用户充值-撤销充值(线下线下二合一)", description = "流水表主键id")
@AutoLog(value = "户充值-撤销充值(线下线下二合一)")
public Result<?> backOutTopUpAll(@RequestBody StClientMemberBackTopUpQueryDto query) throws Exception { public Result<?> backOutTopUpAll(@RequestBody StClientMemberBackTopUpQueryDto query) throws Exception {
if(StringUtils.isBlank(query.getCanteenId())){//当前食堂管理员撤销充值该食堂的充值记录 if(StringUtils.isBlank(query.getCanteenId())){//当前食堂管理员撤销充值该食堂的充值记录
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
@@ -408,32 +404,14 @@ public class StClientMemberBalanceController {
if(null == transactionRecord || StringUtils.isBlank(transactionRecord.getId())){ if(null == transactionRecord || StringUtils.isBlank(transactionRecord.getId())){
return Result.error("订单未找到"); return Result.error("订单未找到");
} }
// List<Integer> onLine = Arrays.asList(MemberEnum.PAYMENT_METHOD_BY_ALI.getCode(),
// MemberEnum.PAYMENT_METHOD_BY_WX.getCode());
// if(!onLine.contains(transactionRecord.getPaymentMethod()) && onLine.contains(query.getPaymentMethod())){
// //原充值方式不是线上,但是撤销充值时是线上提示,不支持线上退款请选择其他退回
// return Result.error("原订单非线上充值,不支持原路退回,请选择其他方式");
// }
// if(onLine.contains(transactionRecord.getPaymentMethod())){//线上退款
// RefundDTO refundDTO = new RefundDTO();
// refundDTO.setPayOrderNo(query.getPayOrderNo());
// refundDTO.setTotalFee(query.getTotalFee());
// refundDTO.setPaymentMethod(query.getPaymentMethod());
// refundDTO.setRemark(query.getRemark());
// if(StringUtils.isBlank(query.getPayOrderNo())){
// return Result.error("商户订单号不能为空");
// }
// return stBbzxOrderInfoService.returnPayInfoTopUpOnline(refundDTO);
// } else {
//线下退款 //线下退款
return iStClientMemberBalanceService.backOutTopUpOffLine(query); return iStClientMemberBalanceService.backOutTopUpOffLine(query);
// }
} }
@PostMapping("/changeBalanceAndIntegral") @PostMapping("/changeBalanceAndIntegral")
@Operation(summary = "用户充值-余额调整", description = "传入条件") @Operation(summary = "用户充值-余额调整", description = "传入条件")
@SendNotification() @AutoLog(value = "用户充值-余额调整")
public Result<?> changeBalanceAndIntegral(@RequestBody StClientMemberChangeBalanceDTO query) { public Result<?> changeBalanceAndIntegral(@RequestBody StClientMemberChangeBalanceDTO query) {
if(StringUtils.isBlank(query.getCanteenId())){//当前食堂管理员撤销充值该食堂的充值记录 if(StringUtils.isBlank(query.getCanteenId())){//当前食堂管理员撤销充值该食堂的充值记录
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
@@ -458,11 +436,24 @@ public class StClientMemberBalanceController {
query.setStartTime(query.getDates().get(0)); query.setStartTime(query.getDates().get(0));
query.setEndTime(query.getDates().get(1)); query.setEndTime(query.getDates().get(1));
} }
String canteenId = query.getCanteenId();
List<String> canteenIdList = new ArrayList<>();
if(StringUtils.isNotBlank(canteenId)){
canteenIdList.add(canteenId);
} else {
//权限校验
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
String canteenId = sysUser.getCanteenId(); List<String> canteenIds = new ArrayList<>();
query.setCanteenId(canteenId); if(sysUser != null){
query.setStatus(1);//消费=101 canteenIds = sysUser.getCanteenIdList().stream().map(ScreenVo::getId).collect(Collectors.toList());
return Result.OK(iStClientMemberTransactionRecordService.pageQuery(query)); canteenIdList.addAll(canteenIds);
}
}
query.setCanteenIdList(canteenIdList);
//消费=101
query.setStatus(101);
return Result.OK(iStClientMemberTransactionRecordService.pageQueryNew(query));
} }
/** /**
@@ -478,22 +469,22 @@ public class StClientMemberBalanceController {
query.setStartTime(split[0]); query.setStartTime(split[0]);
query.setEndTime(split[1]); query.setEndTime(split[1]);
} }
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); String canteenId = query.getCanteenId();
//餐品总库只查询内置食堂 List<String> canteenIdList = new ArrayList<>();
if(sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_0) || sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_1)){ if(StringUtils.isNotBlank(canteenId)){
// 后期分数据权限时在解开注释,此处管理员账户能看到所有食堂数据 canteenIdList.add(canteenId);
// ScreenVo screenVo = new ScreenVo();
// screenVo.setId(CommonConstant.INLAY_CANTEEN_ID);
// canteenIdList.add(screenVo);
} else if (sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_4)) {
//查询当前登录用户的食堂列表
String canteenId = sysUser.getCanteenId();
query.setCanteenId(canteenId);
} else { } else {
return Result.OK(); //权限校验
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<String> canteenIds = new ArrayList<>();
if(sysUser != null){
canteenIds = sysUser.getCanteenIdList().stream().map(ScreenVo::getId).collect(Collectors.toList());
canteenIdList.addAll(canteenIds);
} }
query.setStatus(1);//消费=101 }
List<StClientMemberTransactionRecordVO> statisticsCanteenBusiness = iStClientMemberTransactionRecordService.queryList(query); query.setCanteenIdList(canteenIdList);
query.setStatus(101);
List<StClientMemberTransactionRecordVO> statisticsCanteenBusiness = iStClientMemberTransactionRecordService.queryListNew(query);
StClientMemberTransactionRecordVO sumResult = GenericSumUtil.sumList(statisticsCanteenBusiness, StClientMemberTransactionRecordVO.class); StClientMemberTransactionRecordVO sumResult = GenericSumUtil.sumList(statisticsCanteenBusiness, StClientMemberTransactionRecordVO.class);
StClientMemberTransactionRecordVO stClientMemberTransactionRecordVO = new StClientMemberTransactionRecordVO();//只汇总交易金额 StClientMemberTransactionRecordVO stClientMemberTransactionRecordVO = new StClientMemberTransactionRecordVO();//只汇总交易金额
@@ -512,33 +503,44 @@ public class StClientMemberBalanceController {
query.setStartTime(split[0]); query.setStartTime(split[0]);
query.setEndTime(split[1]); query.setEndTime(split[1]);
} }
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); if(StringUtils.isNotBlank(query.getStartDate())){
//餐品总库只查询内置食堂 query.setStartTime(query.getStartDate());
if(sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_0) || sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_1)){
// 后期分数据权限时在解开注释,此处管理员账户能看到所有食堂数据
// ScreenVo screenVo = new ScreenVo();
// screenVo.setId(CommonConstant.INLAY_CANTEEN_ID);
// canteenIdList.add(screenVo);
} else if (sysUser.getUserIdentity().equals(CommonConstant.USER_IDENTITY_4)) {
//查询当前登录用户的食堂列表
String canteenId = sysUser.getCanteenId();
query.setCanteenId(canteenId);
} else {
return;
} }
query.setStatus(1);//消费=101 if(StringUtils.isNotBlank(query.getEndDate())){
List<StClientMemberTransactionRecordVO> statisticsCanteenBusiness = iStClientMemberTransactionRecordService.queryList(query); query.setEndTime(query.getEndDate());
}
String canteenId = query.getCanteenId();
List<String> canteenIdList = new ArrayList<>();
if(StringUtils.isNotBlank(canteenId)){
canteenIdList.add(canteenId);
} else {
//权限校验
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<String> canteenIds = new ArrayList<>();
if(sysUser != null){
canteenIds = sysUser.getCanteenIdList().stream().map(ScreenVo::getId).collect(Collectors.toList());
canteenIdList.addAll(canteenIds);
}
}
query.setCanteenIdList(canteenIdList);
query.setStatus(101);
List<StClientMemberTransactionRecordVO> statisticsCanteenBusiness = iStClientMemberTransactionRecordService.queryListNew(query);
StClientMemberTransactionRecordVO sumResult = GenericSumUtil.sumList(statisticsCanteenBusiness, StClientMemberTransactionRecordVO.class); StClientMemberTransactionRecordVO sumResult = GenericSumUtil.sumList(statisticsCanteenBusiness, StClientMemberTransactionRecordVO.class);
StClientMemberTransactionRecordVO stClientMemberTransactionRecordVO = new StClientMemberTransactionRecordVO();//只汇总交易金额 StClientMemberTransactionRecordVO stClientMemberTransactionRecordVO = new StClientMemberTransactionRecordVO();//只汇总交易金额
stClientMemberTransactionRecordVO.setSerialNo("总计"); stClientMemberTransactionRecordVO.setUserName("总计");
stClientMemberTransactionRecordVO.setTransactionAmount(sumResult.getTransactionAmount()); stClientMemberTransactionRecordVO.setTransactionAmount(sumResult.getTransactionAmount());
statisticsCanteenBusiness.add(stClientMemberTransactionRecordVO); statisticsCanteenBusiness.add(stClientMemberTransactionRecordVO);
String exportFields = "serialNo|交易流水号,orderNo|交易单号,userName|姓名,phone|手机号,workNo|工号,cardCode|卡号," + // String exportFields = "serialNo|交易流水号,orderNo|交易单号,userName|姓名,,workNo|工号,cardCode|卡号," +
"statusName|操作类型,transactionAmount|交易金额,paymentMethodName|结账方式,businessModelName|消费类型,availableBalance|余额," + // "statusName|操作类型,transactionAmount|交易金额,paymentMethodName|结账方式,businessModelName|消费类型,availableBalance|余额," +
"payTime|结账时间,updateStatusName|操作端,createOne|操作人"; // "payTime|结账时间,updateStatusName|操作端,createOne|操作人";
// "dinnerType|餐次名称,restName|食堂名称,createTime|交易时间,payTime|结账时间,updateStatusName|操作端,createOne|操作人"; // "dinnerType|餐次名称,restName|食堂名称,createTime|交易时间,payTime|结账时间,updateStatusName|操作端,createOne|操作人";
String exportFields = "userName|姓名,workNo|工号,dinnerType|餐次名称,transactionAmount|交易金额,restName|食堂名称,availableBalance|剩余金额,createTime|上传时间,serialNo|交易流水号,orderNo|交易单号,phone|手机号码,cardCode|卡号," +
"statusName|操作类型,paymentMethodName|结账方式,businessModelName|消费类型名称,storedBalance|储值金额变动(元)," +
"updateStatusName|操作端,payTime|扣费时间";
// "dinnerType|餐次名称,restName|食堂名称,,payTime|结账时间,updateStatusName|操作端,createOne|操作人";
ExcelUtils.export(response, "消费明细", statisticsCanteenBusiness, exportFields, "yyyy-MM-dd HH:mm",true); ExcelUtils.export(response, "消费明细", statisticsCanteenBusiness, exportFields, "yyyy-MM-dd HH:mm",true);
} }
@@ -575,70 +577,6 @@ public class StClientMemberBalanceController {
} }
// /**
// * 企业付款到个人微信余额退款后台审核接口
// * @param orderNo
// * @return
// */
// @GetMapping("/btoc/refund/check")
// @Operation(summary= "用户退费-企业付款到个人微信余额退款后台审核接口")
// @SendNotification()
// public Result<?> btocRefund(@RequestParam String orderNo) {
// String auditorId = JwtUtil.getUserId();
// LambdaQueryWrapper<StClientMemberTransactionRecord> queryWrapper = new LambdaQueryWrapper<>();
// queryWrapper.eq(StClientMemberTransactionRecord::getOrderNo, orderNo);
// StClientMemberTransactionRecord one = iStClientMemberTransactionRecordService.getOne(queryWrapper);
// if(null == one){
// return Result.error("申请订单不存在");
// }
// if(one.getStatus().equals(MemberTransactionTypeEnum.B_TO_C_REFUND_301.getCode())){
// return Result.error("订单已经退款成功!");
// }
// TransfersDto transfersDto = new TransfersDto();
// transfersDto.setAmount(one.getTransactionAmount().multiply(BigDecimal.valueOf(100)).intValue());
// SysUser sysUser = feignSystemService.getById(one.getMemberId());
// if(null == sysUser){
// return Result.error("用户不存在");
// }
// if(StringUtils.isBlank(sysUser.getThirdId())){
// return Result.error("用户微信标识为空,请先绑定微信后再试");
// }
// transfersDto.setOpenid(sysUser.getThirdId());
// transfersDto.setCheck_name("FORCE_CHECK");
// transfersDto.setRe_user_name(sysUser.getRealname());
// transfersDto.setDesc("企业付款到个人微信余额退款");
// transfersDto.setPartner_trade_no(StMemberUtil.getOrderNoTransfer(orderNo));
// Result<Boolean> result = iPayInfo.btocRefund(transfersDto);
// one.setCreateBy(auditorId);//审核人ID
// one.setPayTime(new Date());//审核人时间
// one.setIsSync(0);
// iStClientMemberTransactionRecordService.updateById(one);
// if(null != result && result.getCode() == HttpServletResponse.SC_OK && result.getResult()){
// LambdaQueryWrapper<StClientMemberBalance> wrapper = new LambdaQueryWrapper<>();
// wrapper.eq(StClientMemberBalance::getMemberId, one.getMemberId());
// StClientMemberBalance swClientMemberBalance = iStClientMemberBalanceService.getBaseMapper().selectOne(wrapper);
// if (swClientMemberBalance != null) {
// swClientMemberBalance.setTopUpBalance(new BigDecimal(0));
// swClientMemberBalance.setRewardBalance(new BigDecimal(0));
// swClientMemberBalance.setIntegralBalance(0);
// swClientMemberBalance.setUpdateTime(new Date());
// swClientMemberBalance.setCreateBy(one.getCreateBy());
// swClientMemberBalance.setUpdateBy(one.getUpdateBy());
// swClientMemberBalance.setCanteenId(one.getCanteenId());
// swClientMemberBalance.setIsSync(0);
// boolean flag = iStClientMemberBalanceService.saveOrUpdate(swClientMemberBalance);
// if(flag){
// one.setStatus(MemberTransactionTypeEnum.B_TO_C_REFUND_301.getCode());
// one.setIsSync(0);
// iStClientMemberTransactionRecordService.updateById(one);
// }
// }
// return Result.OK("退款成功");
// } else {
// return Result.error("退款失败");
// }
//
// }
//===================================================================================== //=====================================================================================
@@ -673,12 +611,6 @@ public class StClientMemberBalanceController {
} }
// @PostMapping("/updateFeign")
// @Operation(summary = "会员余额更新feign")
// public void memberBalanceUpdateFeign(@RequestBody StClientMemberSpendDTO balance) throws Exception {
// balance.setInvoice(false);
//// iStClientMemberBalanceService.memberSpend(balance); 迁移至client服务更新余额
// }
@PostMapping("/returnSpendFeign") @PostMapping("/returnSpendFeign")
@Operation(summary="会员余额退款") @Operation(summary="会员余额退款")
@@ -0,0 +1,121 @@
package org.jeecg.payment.controller;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.payment.dto.StExceptionRecordDTO;
import org.jeecg.payment.entity.StConsumptionExceptionRecord;
import org.jeecg.payment.service.IStClientMemberLevelDeductRuleService;
import org.jeecg.payment.service.IStConsumptionExceptionRecordService;
import org.jeecg.payment.utils.ExcelUtils;
import org.jeecg.payment.vo.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.List;
@RestController
@RequestMapping("/payment/exceptionRecord")
@Tag(name = "消费异常流水")
public class StConsumptionExceptionRecordController {
@Resource
private IStConsumptionExceptionRecordService stConsumptionExceptionRecordService;
@Resource
private IStClientMemberLevelDeductRuleService iStClientMemberLevelDeductRuleService;
@RequestMapping("/restore")
@Tag(name = "恢复")
@AutoLog(value = "恢复")
public Result<StClientMemberSpendVO> restore(String id) {
StConsumptionExceptionRecord record = stConsumptionExceptionRecordService.getById(id);
StRfidVo stRfidVo = new StRfidVo();
stRfidVo.setUserId(record.getUserId());
stRfidVo.setDeviceCode(record.getDeviceCode());
stRfidVo.setRestId(record.getCanteenId());
stRfidVo.setCardCode(record.getCardCode());
stRfidVo.setPayId(record.getPayId());
stRfidVo.setDateTime(record.getDateTime());
stRfidVo.setSpendMoney(record.getSpendMoney());
stRfidVo.setSecondChargeFlag(record.getSecondChargeFlag());
stRfidVo.setIsCustom(record.getIsCustom());
stRfidVo.setIsRestore(1);
StRfidoffLineVo stRfidoffLineVo = new StRfidoffLineVo();
stRfidoffLineVo.setDeviceCode(stRfidVo.getDeviceCode());
stRfidoffLineVo.setVoList(Collections.singletonList(stRfidVo));
stRfidoffLineVo.setRestId(stRfidVo.getRestId());
//防止循环调用, 写在Controller层
//走扣费逻辑
Result<StClientMemberSpendVO> result = iStClientMemberLevelDeductRuleService.bindUserOfflineCardCode(stRfidoffLineVo,true);
if (result.isSuccess()) {
//更新恢复状态
stConsumptionExceptionRecordService.update(new LambdaUpdateWrapper<StConsumptionExceptionRecord>()
.set(StConsumptionExceptionRecord::getIsRestore, 1)
.eq(StConsumptionExceptionRecord::getId, id));
}
return result;
}
@PostMapping("/pageList")
@Tag(name = "异常流水列表")
@AutoLog(value = "异常流水列表")
public Result<IPage<StExceptionRecordVo>> pageList(@RequestBody StExceptionRecordDTO query){
return Result.OK(stConsumptionExceptionRecordService.exceptionRecordPage(query));
}
@GetMapping("/export")
@AutoLog(value = "异常流水列表导出")
public void getSpendingOrRechargeInfoListExport(HttpServletResponse response,
StExceptionRecordDTO query) {
if(StringUtils.isNotBlank(query.getStartDate())){
query.setStartTime(query.getStartDate());
}
if(StringUtils.isNotBlank(query.getEndDate())){
query.setEndTime(query.getEndDate());
}
List<StExceptionRecordVo> stExceptionRecordVos = stConsumptionExceptionRecordService.exceptionRecordPageExport(query);
if(CollectionUtils.isNotEmpty(stExceptionRecordVos)){
String exportFields = "userName|姓名,phone|手机号,workNo|工号,cardCode|卡号,spendMoney|本次扣费金额,restName|食堂名称,payTime|消费时间,createTime|创建时间";
ExcelUtils.export(response, "异常消费流水", stExceptionRecordVos, exportFields, "yyyy-MM-dd HH:mm",true);
}
}
/**
* 导入消费记录: 针对刷脸机设备出现问题时,从刷脸机导出数据,然后通过导入消费记录,重新计算用户余额
* @param file 文件
* @param canteenId 所属食堂
* @param deviceCode 设备编码
*/
@AutoLog(value = "导入消费记录 刷脸机设备出现问题时 ")
@PostMapping("/importRechargeData")
public Result<?> importRechargeData(@RequestParam(name ="file", required = true) MultipartFile file,
@RequestParam(name = "deviceCode") String deviceCode,
@RequestParam(name = "canteenId") String canteenId) {
try {
List<StRfidVo> stRfidVos = stConsumptionExceptionRecordService.parse(file, deviceCode, canteenId);
StRfidoffLineVo stRfidoffLineVo = new StRfidoffLineVo();
stRfidoffLineVo.setDeviceCode(deviceCode);
stRfidoffLineVo.setVoList(stRfidVos);
stRfidoffLineVo.setRestId(canteenId);
//离线扣费
Result<StClientMemberSpendVO> result = iStClientMemberLevelDeductRuleService.bindUserOfflineCardCode(stRfidoffLineVo,false);
return result;
} catch (Exception e) {
// 异常处理
return Result.error("导入异常");
}
}
}
@@ -1,9 +1,12 @@
package org.jeecg.payment.listUtils; package org.jeecg.payment.listUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Random; import java.util.Random;
import java.util.UUID;
/** /**
* * 订单编码码生成器,生成32位数字编码, * * 订单编码码生成器,生成32位数字编码,
@@ -107,26 +110,10 @@ public class OrderUtils {
*/ */
public static String getOrderCodeV2() { public static String getOrderCodeV2() {
return ORDER_CODE + getDateTimeV2(); return getDateTime() + IdWorker.get32UUID();
} }
/**
* 生成退货单号编码(调用方法)
* @param userId 网站中该用户唯一ID 防止重复
*/
public static String getReturnCode(Integer userId) {
return RETURN_ORDER + getCode(userId);
}
/**
* 生成退款单号编码(调用方法)
* @param userId 网站中该用户唯一ID 防止重复
*/
public static String getRefundCode(Integer userId) {
return REFUND_ORDER + getCode(userId);
}
} }
@@ -3,14 +3,15 @@
*/ */
package org.jeecg.payment.mapper; package org.jeecg.payment.mapper;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.jeecg.payment.entity.StClientMemberLevelDeductRule; import org.jeecg.payment.entity.StClientMemberLevelDeductRule;
import org.jeecg.payment.entity.StClientMemberLevelDemotionTime;
import org.jeecg.payment.vo.StClientMemberLevelDeductRuleVo; import org.jeecg.payment.vo.StClientMemberLevelDeductRuleVo;
import org.jeecg.payment.vo.StClientMemberLevelDemotionTimeVO; import org.jeecg.payment.vo.StClientMemberLevelDemotionTimeVO;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@@ -24,4 +25,5 @@ public interface StClientMemberLevelDeductRuleMapper extends BaseMapper<StClient
*/ */
List<StClientMemberLevelDeductRuleVo> selectStClientMemberLevelDeductRulePage(Page<StClientMemberLevelDeductRuleVo> page, @Param("vo") StClientMemberLevelDemotionTimeVO stClientMemberLevelDeductRule); List<StClientMemberLevelDeductRuleVo> selectStClientMemberLevelDeductRulePage(Page<StClientMemberLevelDeductRuleVo> page, @Param("vo") StClientMemberLevelDemotionTimeVO stClientMemberLevelDeductRule);
Date getMaxTimeByUserId(@Param("userId") String userId);
} }
@@ -1,6 +1,7 @@
package org.jeecg.payment.mapper; package org.jeecg.payment.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.jeecg.payment.dto.StClientMemberTransactionRecordDTO; import org.jeecg.payment.dto.StClientMemberTransactionRecordDTO;
@@ -22,6 +23,9 @@ public interface StClientMemberTransactionRecordMapper extends BaseMapper<StClie
*/ */
List<StClientMemberTransactionRecordVO> pageList(Page<StClientMemberTransactionRecordVO> page, @Param("vo") StClientMemberTransactionRecordDTO query); List<StClientMemberTransactionRecordVO> pageList(Page<StClientMemberTransactionRecordVO> page, @Param("vo") StClientMemberTransactionRecordDTO query);
long pageListCount(@Param("vo") StClientMemberTransactionRecordDTO query);
IPage<StClientMemberTransactionRecordVO> pageList2(Page<StClientMemberTransactionRecordVO> page, @Param("vo") StClientMemberTransactionRecordDTO query);
List<StClientMemberTransactionRecordVO> pageList2( @Param("vo") StClientMemberTransactionRecordDTO query);
/** /**
* 列表查询 * 列表查询
* @return * @return
@@ -0,0 +1,18 @@
package org.jeecg.payment.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.jeecg.payment.dto.StExceptionRecordDTO;
import org.jeecg.payment.entity.StConsumptionExceptionRecord;
import org.jeecg.payment.vo.StExceptionRecordVo;
import java.util.List;
public interface StConsumptionExceptionRecordMapper extends BaseMapper<StConsumptionExceptionRecord> {
IPage<StExceptionRecordVo> exceptionRecordPage(@Param("page") Page<StExceptionRecordVo> page, @Param("query") StExceptionRecordDTO query);
List<StExceptionRecordVo> exceptionRecordPage(@Param("query") StExceptionRecordDTO query);
}
@@ -235,6 +235,7 @@
SUM(oi.order_price) orderPrice, SUM(oi.order_price) orderPrice,
(SELECT COUNT(DISTINCT member_id) FROM st_bbzx_order_info WHERE eat_day = oi.eat_day and `status` = 5 (SELECT COUNT(DISTINCT member_id) FROM st_bbzx_order_info WHERE eat_day = oi.eat_day and `status` = 5
and order_type = 3 and order_type = 3
AND canteen_id = oi.canteen_id
<if test="list != null and list.size() > 0"> <if test="list != null and list.size() > 0">
and canteen_id IN and canteen_id IN
<foreach collection="list" item="canteenId" separator="," open="(" close=")" > <foreach collection="list" item="canteenId" separator="," open="(" close=")" >
@@ -242,7 +243,7 @@
</foreach> </foreach>
</if> </if>
<if test="startDate != '' and startDate != null "> <if test="startDate != '' and startDate != null ">
and eat_day between #{startDate} and #{endDate} and DATE_FORMAT(create_time,'%Y-%m-%d') between #{startDate} and #{endDate}
</if> </if>
) AS totalNum ) AS totalNum
FROM FROM
@@ -258,17 +259,19 @@
</foreach> </foreach>
</if> </if>
<if test="startDate != '' and startDate != null "> <if test="startDate != '' and startDate != null ">
and oi.eat_day between #{startDate} and #{endDate} and DATE_FORMAT(oi.create_time,'%Y-%m-%d') between #{startDate} and #{endDate}
</if> </if>
GROUP BY GROUP BY
oi.canteen_id, oi.canteen_id,
oi.eat_day oi.eat_day,
r.rest_name
order by oi.eat_day desc order by oi.eat_day desc
</select> </select>
<select id="statisticsTheAmountSpentEveryMember" <select id="statisticsTheAmountSpentEveryMember"
resultType="org.jeecg.payment.vo.StatisticsTheAmountSpentVo"> resultType="org.jeecg.payment.vo.StatisticsTheAmountSpentVo">
SELECT SELECT
u.realname, u.realname,
sr.rest_name as restName,
pay.realname as payRealname, pay.realname as payRealname,
u.work_no, u.work_no,
CONCAT( CONCAT(
@@ -306,8 +309,9 @@
) AS totalNum ) AS totalNum
FROM FROM
st_bbzx_order_info oi st_bbzx_order_info oi
JOIN sys_user_sub u ON oi.member_id = u.id LEFT JOIN sys_user_sub u ON oi.member_id = u.id
JOIN sys_user_sub pay ON oi.pay_member_id = pay.id LEFT JOIN sys_user_sub pay ON oi.pay_member_id = pay.id
LEFT JOIN st_base_restaurant AS sr ON sr.id = oi.canteen_id
LEFT JOIN sys_pay_depart direct_depart ON pay.depart_ids = direct_depart.id AND direct_depart.del_flag = '0' LEFT JOIN sys_pay_depart direct_depart ON pay.depart_ids = direct_depart.id AND direct_depart.del_flag = '0'
LEFT JOIN sys_pay_depart parent_depart ON direct_depart.parent_id = parent_depart.id AND parent_depart.del_flag = '0' LEFT JOIN sys_pay_depart parent_depart ON direct_depart.parent_id = parent_depart.id AND parent_depart.del_flag = '0'
WHERE WHERE
@@ -78,7 +78,7 @@
and b.work_no like CONCAT('%',#{vo.workNo,jdbcType=VARCHAR},'%') and b.work_no like CONCAT('%',#{vo.workNo,jdbcType=VARCHAR},'%')
</if> </if>
<if test="vo.startTime != null and vo.startTime != '' and vo.endTime != null and vo.endTime != ''"> <if test="vo.startTime != null and vo.startTime != '' and vo.endTime != null and vo.endTime != ''">
and DATE_FORMAT(a.first_top_up_time,'%Y-%m-%d') between #{vo.startTime} and #{vo.endTime} and DATE_FORMAT(a.last_consumption_time,'%Y-%m-%d') between #{vo.startTime} and #{vo.endTime}
</if> </if>
<if test="vo.list != null"> <if test="vo.list != null">
and b.depart_ids in and b.depart_ids in
@@ -156,6 +156,7 @@
<if test="invoiceBalance != null"> <if test="invoiceBalance != null">
invoice_total = invoice_total + #{invoiceBalance,jdbcType=DECIMAL}, invoice_total = invoice_total + #{invoiceBalance,jdbcType=DECIMAL},
</if> </if>
update_time = now(),
is_sync = 0 is_sync = 0
</set> </set>
where id = #{id} where id = #{id}
@@ -17,5 +17,8 @@
</if> </if>
order by is_enable desc, create_time desc order by is_enable desc, create_time desc
</select> </select>
<select id="getMaxTimeByUserId" resultType="cn.hutool.core.date.DateTime">
SELECT MAX(create_time) FROM st_bbzx_order_info WHERE member_id = #{userId}
</select>
</mapper> </mapper>
@@ -38,7 +38,7 @@
a.id, a.id,
a.serial_no as serialNo, a.serial_no as serialNo,
a.order_no as orderNo, a.order_no as orderNo,
c.realname as userName, IF(a.member_id = a.pay_member_id,c.realname,CONCAT(c.realname,'-',pay.realname)) as userName,
sboi.serial_no as cardCode, sboi.serial_no as cardCode,
sboi.business_model AS businessModel, sboi.business_model AS businessModel,
pay.realname as payUserName, pay.realname as payUserName,
@@ -67,8 +67,8 @@
LEFT JOIN st_client_member_balance AS b ON a.member_id = b.member_id LEFT JOIN st_client_member_balance AS b ON a.member_id = b.member_id
LEFT JOIN st_bbzx_order_info AS sboi ON sboi.order_no = a.order_no LEFT JOIN st_bbzx_order_info AS sboi ON sboi.order_no = a.order_no
LEFT JOIN st_base_restaurant AS br ON br.id = a.canteen_id LEFT JOIN st_base_restaurant AS br ON br.id = a.canteen_id
LEFT JOIN sys_user_sub AS c ON a.member_id = c.id LEFT JOIN sys_user_sub AS c ON a.pay_member_id = c.id
LEFT JOIN sys_user_sub AS pay ON a.pay_member_id = pay.id LEFT JOIN sys_user_sub AS pay ON a.member_id = pay.id
LEFT JOIN sys_pay_depart direct_depart ON pay.depart_ids = direct_depart.id AND direct_depart.del_flag = '0' LEFT JOIN sys_pay_depart direct_depart ON pay.depart_ids = direct_depart.id AND direct_depart.del_flag = '0'
LEFT JOIN sys_pay_depart parent_depart ON direct_depart.parent_id = parent_depart.id AND parent_depart.del_flag = '0' LEFT JOIN sys_pay_depart parent_depart ON direct_depart.parent_id = parent_depart.id AND parent_depart.del_flag = '0'
WHERE a.is_del = 0 WHERE a.is_del = 0
@@ -120,12 +120,169 @@
<if test="vo.canteenId != null and vo.canteenId != ''"> <if test="vo.canteenId != null and vo.canteenId != ''">
and a.canteen_id = #{vo.canteenId} and a.canteen_id = #{vo.canteenId}
</if> </if>
<if test="vo.dinnerType != null and vo.dinnerType != ''">
and sboi.dinner_type = #{vo.dinnerType}
</if>
<if test="vo.list != null"> <if test="vo.list != null">
and pay.depart_ids in and pay.depart_ids in
<foreach item="departId" collection="vo.list" open="(" separator="," close=")"> <foreach item="departId" collection="vo.list" open="(" separator="," close=")">
#{departId} #{departId}
</foreach> </foreach>
</if> </if>
<if test="vo.canteenIdList != null and vo.canteenIdList.size() > 0">
and a.canteen_id IN
<foreach collection="vo.canteenIdList" item="canteenId" separator="," open="(" close=")">
#{canteenId}
</foreach>
</if>
order by a.create_time
<choose>
<when test="vo.status != null and vo.status == 3 ">
asc
</when>
<otherwise>
desc
</otherwise>
</choose>
</select>
<select id="pageListCount" resultType="java.lang.Long">
SELECT
count(a.id)
FROM
st_client_member_transaction_record as a
<if test="vo.dinnerType != null and vo.dinnerType != ''">
LEFT JOIN st_bbzx_order_info sboi ON a.order_no = sboi.order_no
</if>
LEFT JOIN sys_user_sub AS c ON a.pay_member_id = c.id
LEFT JOIN sys_user_sub AS pay ON a.member_id = pay.id
WHERE a.is_del = 0
<if test="vo.startTime != null and vo.endTime !=''">
<choose>
<when test="vo.payTimeStatus == 1">
and DATE_FORMAT(a.pay_time,'%Y-%m-%d') &gt;= DATE_FORMAT(#{vo.startTime},'%Y-%m-%d')
and DATE_FORMAT(a.pay_time,'%Y-%m-%d') &lt;= DATE_FORMAT(#{vo.endTime},'%Y-%m-%d')
</when>
<when test="vo.payTimeStatus == 2">
and DATE_FORMAT(a.create_time,'%Y-%m-%d') &gt;= DATE_FORMAT(#{vo.startTime},'%Y-%m-%d')
and DATE_FORMAT(a.create_time,'%Y-%m-%d') &lt;= DATE_FORMAT(#{vo.endTime},'%Y-%m-%d')
</when>
</choose>
</if>
<if test="vo.status != null ">
and a.STATUS = #{vo.status}
</if>
<if test="vo.list != null">
and c.depart_ids in
<foreach item="departId" collection="vo.list" open="(" separator="," close=")">
#{departId}
</foreach>
</if>
<if test="vo.phone != null and vo.phone != ''">
and c.phone like CONCAT('%',#{vo.phone,jdbcType=VARCHAR},'%')
</if>
<if test="vo.paymentMethod != null and vo.paymentMethod != ''">
and a.payment_method = #{vo.paymentMethod}
</if>
<if test="vo.workNo != null and vo.workNo != ''">
and c.work_no like CONCAT('%',#{vo.workNo,jdbcType=VARCHAR},'%')
</if>
<if test="vo.userName != null and vo.userName != ''">
and c.realname like CONCAT('%',#{vo.userName,jdbcType=VARCHAR},'%')
</if>
<if test="vo.canteenId != null and vo.canteenId != ''">
and a.canteen_id = #{vo.canteenId}
</if>
<if test="vo.dinnerType != null and vo.dinnerType != ''">
and sboi.dinner_type = #{vo.dinnerType}
</if>
<if test="vo.canteenIdList != null and vo.canteenIdList.size() > 0">
and a.canteen_id IN
<foreach collection="vo.canteenIdList" item="canteenId" separator="," open="(" close=")">
#{canteenId}
</foreach>
</if>
</select>
<select id="pageList2" resultType="org.jeecg.payment.vo.StClientMemberTransactionRecordVO">
SELECT DISTINCT
a.id,
a.serial_no as serialNo,
a.order_no as orderNo,
IF(a.member_id = a.pay_member_id,c.realname,CONCAT(c.realname,'-',pay.realname)) as userName,
c.phone,
c.work_no as workNo,
a.status,
a.transaction_amount as transactionAmount,
a.payment_method as paymentMethod,
a.available_balance as availableBalance,
a.reward_balance as rewardBalance,
a.stored_balance as storedBalance,
a.integral_balance as integralBalance,
a.create_time as createTime,
a.pay_time as payTime,
sr.rest_name as restName,
a.update_status as updateStatus
FROM
st_client_member_transaction_record as a
<if test="vo.dinnerType != null and vo.dinnerType != ''">
LEFT JOIN st_bbzx_order_info sboi ON a.order_no = sboi.order_no
</if>
LEFT JOIN st_base_restaurant AS sr ON sr.id = a.canteen_id
LEFT JOIN sys_user_sub AS c ON a.pay_member_id = c.id
LEFT JOIN sys_user_sub AS pay ON a.member_id = pay.id
WHERE a.is_del = 0
<if test="vo.startTime != null and vo.endTime !=''">
<choose>
<when test="vo.payTimeStatus == 1">
and DATE_FORMAT(a.pay_time,'%Y-%m-%d') &gt;= DATE_FORMAT(#{vo.startTime},'%Y-%m-%d')
and DATE_FORMAT(a.pay_time,'%Y-%m-%d') &lt;= DATE_FORMAT(#{vo.endTime},'%Y-%m-%d')
</when>
<when test="vo.payTimeStatus == 2">
and DATE_FORMAT(a.create_time,'%Y-%m-%d') &gt;= DATE_FORMAT(#{vo.startTime},'%Y-%m-%d')
and DATE_FORMAT(a.create_time,'%Y-%m-%d') &lt;= DATE_FORMAT(#{vo.endTime},'%Y-%m-%d')
</when>
</choose>
</if>
<if test="vo.status != null ">
and a.STATUS = #{vo.status}
</if>
<if test="vo.list != null">
and c.depart_ids in
<foreach item="departId" collection="vo.list" open="(" separator="," close=")">
#{departId}
</foreach>
</if>
<if test="vo.phone != null and vo.phone != ''">
and c.phone like CONCAT('%',#{vo.phone,jdbcType=VARCHAR},'%')
</if>
<if test="vo.paymentMethod != null and vo.paymentMethod != ''">
and a.payment_method = #{vo.paymentMethod}
</if>
<if test="vo.workNo != null and vo.workNo != ''">
and c.work_no like CONCAT('%',#{vo.workNo,jdbcType=VARCHAR},'%')
</if>
<if test="vo.userName != null and vo.userName != ''">
and c.realname like CONCAT('%',#{vo.userName,jdbcType=VARCHAR},'%')
</if>
<if test="vo.canteenId != null and vo.canteenId != ''">
and a.canteen_id = #{vo.canteenId}
</if>
<if test="vo.dinnerType != null and vo.dinnerType != ''">
and sboi.dinner_type = #{vo.dinnerType}
</if>
<if test="vo.canteenIdList != null and vo.canteenIdList.size() > 0">
and a.canteen_id IN
<foreach collection="vo.canteenIdList" item="canteenId" separator="," open="(" close=")">
#{canteenId}
</foreach>
</if>
order by a.create_time desc order by a.create_time desc
</select> </select>
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.payment.mapper.StConsumptionExceptionRecordMapper">
<select id="exceptionRecordPage" resultType="org.jeecg.payment.vo.StExceptionRecordVo">
SELECT
a.id,
a.card_code,
a.spend_money,
a.is_custom,
a.is_restore,
a.date_time,
a.create_time,
a.update_time,
a.pay_time,
a.error_msg,
u.realname as userName,
sr.rest_name as restName,
CONCAT(
IFNULL(parent_depart.depart_name, ''),
IF(parent_depart.depart_name IS NOT NULL AND direct_depart.depart_name IS NOT NULL, '->', ''),
IFNULL(direct_depart.depart_name, '')
) as deptName,
u.phone,
u.work_no as workNo
FROM
st_consumption_exception_record a
LEFT JOIN sys_user_sub AS u ON a.user_id = u.id
LEFT JOIN sys_pay_depart direct_depart ON u.depart_ids = direct_depart.id AND direct_depart.del_flag = '0'
LEFT JOIN sys_pay_depart parent_depart ON direct_depart.parent_id = parent_depart.id AND parent_depart.del_flag = '0'
LEFT JOIN st_base_restaurant AS sr ON a.canteen_id = sr.id
WHERE 1 = 1
<if test="query.phone != null and query.phone != ''">
and u.phone like CONCAT('%',#{query.phone},'%')
</if>
<if test="query.workNo != null and query.workNo != ''">
and u.work_no like CONCAT('%',#{query.workNo},'%')
</if>
<if test="query.userName != null and query.userName != ''">
and u.realname like CONCAT('%',#{query.userName},'%')
</if>
<if test="query.startTime != null and query.endTime !=''">
and a.pay_time between #{query.startTime} and #{query.endTime}
</if>
<if test="query.list != null">
and u.depart_ids in
<foreach item="departId" collection="query.list" open="(" separator="," close=")">
#{departId}
</foreach>
</if>
<if test="query.canteenIdList != null and query.canteenIdList.size() > 0">
and a.canteen_id IN
<foreach collection="query.canteenIdList" item="canteenId" separator="," open="(" close=")">
#{canteenId}
</foreach>
</if>
order by a.create_time desc
</select>
</mapper>
@@ -44,8 +44,13 @@ public interface IStClientMemberLevelDeductRuleService extends JeecgService<StCl
*/ */
StClientMemberLevelDeductRuleVo bulidStClientMemberLevelDeductRule(StClientMemberLevelDeductRuleVo vo, StClientMemberLevelDeductRule memberLevel); StClientMemberLevelDeductRuleVo bulidStClientMemberLevelDeductRule(StClientMemberLevelDeductRuleVo vo, StClientMemberLevelDeductRule memberLevel);
/**
Result<StClientMemberSpendVO> bindUserOfflineCardCode(@RequestBody StRfidoffLineVo stRfidoffLineVo); *
* @param stRfidoffLineVo
* @param onlineStatus true 在线扣费 false 离线扣费
* @return
*/
Result<StClientMemberSpendVO> bindUserOfflineCardCode(@RequestBody StRfidoffLineVo stRfidoffLineVo,boolean onlineStatus);
/** /**
@@ -24,6 +24,8 @@ public interface IStClientMemberTransactionRecordService extends JeecgService<St
*/ */
IPage<StClientMemberTransactionRecordVO> pageQuery(StClientMemberTransactionRecordDTO query); IPage<StClientMemberTransactionRecordVO> pageQuery(StClientMemberTransactionRecordDTO query);
IPage<StClientMemberTransactionRecordVO> pageQueryNew(StClientMemberTransactionRecordDTO query);
/** /**
* 列表查询导出 * 列表查询导出
* *
@@ -32,6 +34,14 @@ public interface IStClientMemberTransactionRecordService extends JeecgService<St
*/ */
List<StClientMemberTransactionRecordVO> queryList(StClientMemberTransactionRecordDTO query); List<StClientMemberTransactionRecordVO> queryList(StClientMemberTransactionRecordDTO query);
/**
* 列表查询导出
*
* @param query
* @return
*/
List<StClientMemberTransactionRecordVO> queryListNew(StClientMemberTransactionRecordDTO query);
IPage<StClientMemberTransactionRecordVO> pageBalanceRefundList(Page<StClientMemberTransactionRecordVO> page, StClientMemberTransactionRecordDTO query); IPage<StClientMemberTransactionRecordVO> pageBalanceRefundList(Page<StClientMemberTransactionRecordVO> page, StClientMemberTransactionRecordDTO query);
InOutRecordInfoVo getOneInOutInfo(String recordId); InOutRecordInfoVo getOneInOutInfo(String recordId);
@@ -0,0 +1,24 @@
package org.jeecg.payment.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.payment.dto.StExceptionRecordDTO;
import org.jeecg.payment.entity.StConsumptionExceptionRecord;
import org.jeecg.payment.vo.StExceptionRecordVo;
import org.jeecg.payment.vo.StRfidVo;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
public interface IStConsumptionExceptionRecordService extends IService<StConsumptionExceptionRecord> {
IPage<StExceptionRecordVo> exceptionRecordPage(StExceptionRecordDTO query);
List<StExceptionRecordVo> exceptionRecordPageExport(StExceptionRecordDTO query);
List<StRfidVo> parse(MultipartFile file, String defaultDeviceCode, String defaultRestId) throws IOException;
}
@@ -8,6 +8,7 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xkcoding.http.util.StringUtil; import com.xkcoding.http.util.StringUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -752,7 +753,7 @@ public class StBbzxOrderInfoServiceImpl extends JeecgServiceImpl<StBbzxOrderInfo
public StBbzxOrderInfo buildOrderInfoNew(Date dateTime,String restId,String dinnerType,String plateNumber,String userId,String memberName,String memberPhone,Integer deductionType,StClientMemberLevelDeductRuleVo levelDeductRuleVo , String remark,StRfidVo stRfidVo){ public StBbzxOrderInfo buildOrderInfoNew(Date dateTime,String restId,String dinnerType,String plateNumber,String userId,String memberName,String memberPhone,Integer deductionType,StClientMemberLevelDeductRuleVo levelDeductRuleVo , String remark,StRfidVo stRfidVo){
StBbzxOrderInfo stBbzxOrderInfo = new StBbzxOrderInfo(); StBbzxOrderInfo stBbzxOrderInfo = new StBbzxOrderInfo();
stBbzxOrderInfo.setOrderType(3); stBbzxOrderInfo.setOrderType(3);
String orderNo = OrderUtils.getOrderCode(10); String orderNo = OrderUtils.getOrderCodeV2();
stBbzxOrderInfo.setOrderNo(orderNo); stBbzxOrderInfo.setOrderNo(orderNo);
stBbzxOrderInfo.setSerialNo(stRfidVo.getCardCode()); stBbzxOrderInfo.setSerialNo(stRfidVo.getCardCode());
stBbzxOrderInfo.setDinnerType(dinnerType); stBbzxOrderInfo.setDinnerType(dinnerType);
@@ -775,6 +776,7 @@ public class StBbzxOrderInfoServiceImpl extends JeecgServiceImpl<StBbzxOrderInfo
stBbzxOrderInfo.setOrderPrice(stRfidVo.getSpendMoney()); stBbzxOrderInfo.setOrderPrice(stRfidVo.getSpendMoney());
stBbzxOrderInfo.setCustomerPrice(stRfidVo.getSpendMoney()); stBbzxOrderInfo.setCustomerPrice(stRfidVo.getSpendMoney());
} }
stBbzxOrderInfo.setDeviceCode(stRfidVo.getDeviceCode());
stBbzxOrderInfo.setStatus(OrderStatus.ORDER_STATUS_WAIT_CHECK_OUT.getCode());//待结账 stBbzxOrderInfo.setStatus(OrderStatus.ORDER_STATUS_WAIT_CHECK_OUT.getCode());//待结账
stBbzxOrderInfo.setCanteenId(restId); stBbzxOrderInfo.setCanteenId(restId);
stBbzxOrderInfo.setBusinessModel(deductionType); stBbzxOrderInfo.setBusinessModel(deductionType);
@@ -812,8 +814,9 @@ public class StBbzxOrderInfoServiceImpl extends JeecgServiceImpl<StBbzxOrderInfo
String memberPhone,Integer deductionType,StClientMemberLevelDeductRuleVo levelDeductRuleVo , String memberPhone,Integer deductionType,StClientMemberLevelDeductRuleVo levelDeductRuleVo ,
String remark,StRfidVo stRfidVo,StMiniMineBalanceVo miniMineBalanceVo){ String remark,StRfidVo stRfidVo,StMiniMineBalanceVo miniMineBalanceVo){
StBbzxOrderInfo stBbzxOrderInfo = new StBbzxOrderInfo(); StBbzxOrderInfo stBbzxOrderInfo = new StBbzxOrderInfo();
stBbzxOrderInfo.setDeviceCode(stRfidVo.getDeviceCode());
stBbzxOrderInfo.setOrderType(3); stBbzxOrderInfo.setOrderType(3);
String orderNo = OrderUtils.getOrderCode(10); String orderNo = OrderUtils.getOrderCodeV2();
stBbzxOrderInfo.setOrderNo(orderNo); stBbzxOrderInfo.setOrderNo(orderNo);
stBbzxOrderInfo.setSerialNo(miniMineBalanceVo.getCardCode()); stBbzxOrderInfo.setSerialNo(miniMineBalanceVo.getCardCode());
stBbzxOrderInfo.setDinnerType(dinnerType); stBbzxOrderInfo.setDinnerType(dinnerType);
@@ -335,6 +335,7 @@ public class StClientMemberBalanceServiceImpl extends JeecgServiceImpl<StClientM
// 4. 记录充值流水 // 4. 记录充值流水
String orderNo = StMemberUtil.getOrderNo(); String orderNo = StMemberUtil.getOrderNo();
model.setMemberId(swClientMemberBalance.getMemberId()); model.setMemberId(swClientMemberBalance.getMemberId());
model.setPayMemberId(swClientMemberBalance.getMemberId());
model.setStatus(MemberTransactionTypeEnum.PAY.getCode()); model.setStatus(MemberTransactionTypeEnum.PAY.getCode());
model.setTransactionAmount(query.getTopUpBalance()); model.setTransactionAmount(query.getTopUpBalance());
model.setPaymentMethod(query.getPaymentMethod()); model.setPaymentMethod(query.getPaymentMethod());
@@ -1638,6 +1639,7 @@ public class StClientMemberBalanceServiceImpl extends JeecgServiceImpl<StClientM
iStBbzxOrderInfoPayService.save(stBbzxOrderInfoPay); iStBbzxOrderInfoPayService.save(stBbzxOrderInfoPay);
//消费记录数据添加 //消费记录数据添加
StClientMemberTransactionRecord mtr = new StClientMemberTransactionRecord(); StClientMemberTransactionRecord mtr = new StClientMemberTransactionRecord();
mtr.setDeviceCode(StringUtils.isNotBlank(stBbzxOrderInfo.getDeviceCode()) ? stBbzxOrderInfo.getDeviceCode() : null );
mtr.setMemberId(stBbzxOrderInfo.getMemberId()); mtr.setMemberId(stBbzxOrderInfo.getMemberId());
mtr.setPayMemberId(query.getId()); mtr.setPayMemberId(query.getId());
mtr.setSerialNo(RandomUtil.randomNumbers(19)); mtr.setSerialNo(RandomUtil.randomNumbers(19));
@@ -1907,9 +1909,9 @@ public class StClientMemberBalanceServiceImpl extends JeecgServiceImpl<StClientM
StClientMemberTransactionRecord model = new StClientMemberTransactionRecord(); StClientMemberTransactionRecord model = new StClientMemberTransactionRecord();
StClientMemberBalance swClientMemberBalance = baseMapper.selectById(query.getId()); StClientMemberBalance swClientMemberBalance = baseMapper.selectById(query.getId());
if (swClientMemberBalance != null) { if (swClientMemberBalance != null) {
model.setRemark(query.getRemark());
model.setCanteenId(query.getCanteenId()); model.setCanteenId(query.getCanteenId());
model.setMemberId(swClientMemberBalance.getMemberId()); model.setMemberId(swClientMemberBalance.getMemberId());
model.setMemberId(query.getCanteenId());
model.setSerialNo(StMemberUtil.getSerialNo()); model.setSerialNo(StMemberUtil.getSerialNo());
model.setStatus(status); model.setStatus(status);
if (query.getIntegralBalance() != null) { if (query.getIntegralBalance() != null) {
@@ -1918,11 +1920,11 @@ public class StClientMemberBalanceServiceImpl extends JeecgServiceImpl<StClientM
BigDecimal v=new BigDecimal("0"); BigDecimal v=new BigDecimal("0");
if (query.getTopUpBalance() != null) { if (query.getTopUpBalance() != null) {
model.setStoredBalance(query.getTopUpBalance()); model.setStoredBalance(query.getTopUpBalance());
v.add(query.getTopUpBalance()); v = v.add(query.getTopUpBalance()); //BigDecimal 是不可变类 返回值重新赋值给v
} }
if (query.getRewardBalance() != null) { if (query.getRewardBalance() != null) {
model.setRewardBalance(query.getRewardBalance()); model.setRewardBalance(query.getRewardBalance());
v.add(query.getRewardBalance()); v = v.add(query.getRewardBalance()); //BigDecimal 是不可变类 返回值重新赋值给v
} }
//操作金额 //操作金额
model.setTransactionAmount(v); model.setTransactionAmount(v);
@@ -16,13 +16,16 @@ import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.service.impl.JeecgServiceImpl; import org.jeecg.common.system.base.service.impl.JeecgServiceImpl;
import org.jeecg.common.util.DateUtils; import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisLockUtil;
import org.jeecg.payment.entity.StBbzxOrderInfo; import org.jeecg.payment.entity.StBbzxOrderInfo;
import org.jeecg.payment.entity.StClientMemberLevelDeductRule; import org.jeecg.payment.entity.StClientMemberLevelDeductRule;
import org.jeecg.payment.entity.StConsumptionExceptionRecord;
import org.jeecg.payment.enums.DeductionTypeEnum; import org.jeecg.payment.enums.DeductionTypeEnum;
import org.jeecg.payment.mapper.StClientMemberLevelDeductRuleMapper; import org.jeecg.payment.mapper.StClientMemberLevelDeductRuleMapper;
import org.jeecg.payment.service.IStBbzxOrderInfoService; import org.jeecg.payment.service.IStBbzxOrderInfoService;
import org.jeecg.payment.service.IStClientMemberBalanceService; import org.jeecg.payment.service.IStClientMemberBalanceService;
import org.jeecg.payment.service.IStClientMemberLevelDeductRuleService; import org.jeecg.payment.service.IStClientMemberLevelDeductRuleService;
import org.jeecg.payment.service.IStConsumptionExceptionRecordService;
import org.jeecg.payment.utils.MealGroupingUtil; import org.jeecg.payment.utils.MealGroupingUtil;
import org.jeecg.payment.vo.*; import org.jeecg.payment.vo.*;
import org.jeecg.restaurant.entity.SlBaseDinnerTime; import org.jeecg.restaurant.entity.SlBaseDinnerTime;
@@ -32,14 +35,11 @@ import org.jeecg.restaurant.service.ISlBaseDinnerTimeService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.Date; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -61,6 +61,10 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
@Autowired @Autowired
private ISlBaseDinnerTimeService stBaseDinnerTimeService; private ISlBaseDinnerTimeService stBaseDinnerTimeService;
@Resource
private RedisLockUtil redisLockUtil;
@Resource
private IStConsumptionExceptionRecordService stConsumptionExceptionRecordService;
@Override @Override
@@ -232,23 +236,235 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
} }
// @Override
// public Result<StClientMemberSpendVO> bindUserOfflineCardCode(@RequestBody StRfidoffLineVo stRfidoffLineVo){
// String deviceCode = stRfidoffLineVo.getDeviceCode();
// String restId = stRfidoffLineVo.getRestId();
// List<StRfidVo> voListAll = stRfidoffLineVo.getVoList();
// if(CollectionUtils.isEmpty(voListAll)){
// return Result.error("扣费信息不能为空");
// }
// //扣费规则(扣费类型(1:固定扣费,2:固定+补贴扣费,3:按量扣费,4:自定义金额))
// StClientMemberLevelDeductRuleVo levelDeductRuleVo = this.getDeductRuleByCanteenId(restId);
// if(voListAll.size() > 1){//离线扣费
// //加异步处理
// CompletableFuture.runAsync(() -> {
// unifiedDeductionInterface(voListAll,restId,deviceCode,levelDeductRuleVo,false);
// });
// } else {//在线扣费
// return unifiedDeductionInterface(voListAll,restId,deviceCode,levelDeductRuleVo,true);
// }
// return Result.OK("扣费成功");
// }
/**
* 过滤与当前时间相差小于1分钟的记录
*/
private static List<StRfidVo> filterRecentThanOneMinute(List<StRfidVo> dataList,long maxTime) {
long oneMinuteMs = 60 * 1000; // 1分钟 = 60000毫秒
return dataList.stream()
.filter(vo -> {
// 跳过 dateTime 为空或格式错误的记录(视为无效数据,直接过滤)
if (StringUtils.isBlank(vo.getDateTime())) {
return false;
}
try {
long recordTime = Long.parseLong(vo.getDateTime()); // 记录时间戳(毫秒)
long timeDiff = maxTime - recordTime; // 时间差(当前时间 - 记录时间)
// 保留:时间差 >= 1分钟(或记录时间在当前时间之后,避免未来时间戳)
return timeDiff >= oneMinuteMs || recordTime > maxTime;
} catch (NumberFormatException e) {
// dateTime 不是有效数字(如非时间戳字符串),视为无效数据
return false;
}
})
.collect(Collectors.toList());
}
/**
* 移除时间戳(dateTime)重复的记录(保留第一条)
*/
private static List<StRfidVo> filterDuplicateTimestamp(List<StRfidVo> dataList) {
// 使用 LinkedHashMap 保留插入顺序,key=dateTimevalue=StRfidVo(重复时覆盖,仅保留最后一次出现的记录)
Map<String, StRfidVo> uniqueMap = new LinkedHashMap<>();
for (StRfidVo vo : dataList) {
String dateTime = vo.getDateTime();
if (StringUtils.isNotBlank(dateTime)) { // 仅对 dateTime 非空的记录去重
uniqueMap.put(dateTime, vo);
} else {
// dateTime 为空的记录直接保留(已通过步骤1过滤无效数据,此处可忽略)
uniqueMap.put(UUID.randomUUID().toString(), vo); // 用UUID避免key冲突
}
}
// 转换为 List 并返回
return new ArrayList<>(uniqueMap.values());
}
//用户一天 一餐 不是二次扣费的数据 , 只留一条
//非二次扣费, 只保留一条正常扣费, 剩下的数据添加到消费异常记录表中
public List<StRfidVo> processUserMealDataSimplified(List<StRfidVo> dataList,String restId) {
if (dataList == null || dataList.isEmpty()) {
return new ArrayList<>();
}
List<SlBaseDinnerTime> dinnerTimeList = stBaseDinnerTimeService.list(new LambdaQueryWrapper<SlBaseDinnerTime>()
.eq(SlBaseDinnerTime::getRestId, restId)
.orderByAsc(SlBaseDinnerTime::getEndTime));
//异常数据
List<StRfidVo> unselectedData = new ArrayList<>();
// 按用户ID、日期、餐次分组,然后处理每组数据
List<StRfidVo> collect = dataList.stream()
.collect(Collectors.groupingBy(vo ->
vo.getUserId() + "_" + DateUtils.formatDate(new Date(Long.parseLong(vo.getDateTime())), "yyyy-MM-dd") + "_" + getDinnerType(dinnerTimeList, vo.getDateTime())))
.values()
.stream()
.flatMap(group -> {
//(stRfidVo.getSecondChargeFlag() == null || stRfidVo.getSecondChargeFlag() == 0) && (stRfidVo.getIsCustom() == null || stRfidVo.getIsCustom() == 0)
// 分离二次扣费和非二次扣费数据
List<StRfidVo> secondCharge = group.stream()
.filter(vo -> (vo.getSecondChargeFlag() != null && vo.getSecondChargeFlag() == 1) || (vo.getIsCustom() != null && vo.getIsCustom() == 1) )
.collect(Collectors.toList());
List<StRfidVo> nonSecondCharge = group.stream()
.filter(vo -> (vo.getSecondChargeFlag() == null || vo.getSecondChargeFlag() == 0) && (vo.getIsCustom() == null || vo.getIsCustom() == 0))
.collect(Collectors.toList());
// 非二次扣费数据只保留一条
List<StRfidVo> resultGroup = new ArrayList<>();
if (!nonSecondCharge.isEmpty()) {
StRfidVo stRfidVo = nonSecondCharge.stream()
.min((vo1, vo2) -> compareByDateTime(vo1.getDateTime(), vo2.getDateTime()))
.orElse(nonSecondCharge.get(0));
resultGroup.add(stRfidVo);
List<StRfidVo> remaining = nonSecondCharge.stream()
.filter(vo -> !vo.equals(stRfidVo))
.collect(Collectors.toList());
unselectedData.addAll(remaining);
}
resultGroup.addAll(secondCharge);
return resultGroup.stream();
})
.collect(Collectors.toList());
//保存异常消费数据
if(CollectionUtils.isNotEmpty(unselectedData)){
saveExceptionRecord(unselectedData);
}
return collect;
}
//保存异常消费数据
private void saveExceptionRecord(List<StRfidVo> unselectedData){
List<StConsumptionExceptionRecord> unselectedEntities = unselectedData.stream()
.map(vo -> {
StConsumptionExceptionRecord entity = new StConsumptionExceptionRecord();
if(vo.getIsRestore()!= null){
entity.setIsRestore(vo.getIsRestore());
}
if(StringUtils.isNotBlank(vo.getErrorMsg())){
entity.setErrorMsg(vo.getErrorMsg());
}
entity.setUserId(vo.getUserId());
entity.setDeviceCode(vo.getDeviceCode());
entity.setCanteenId(vo.getRestId());
entity.setCardCode(vo.getCardCode());
entity.setPayId(vo.getPayId());
entity.setDateTime(vo.getDateTime());
entity.setSpendMoney(vo.getSpendMoney());
entity.setSecondChargeFlag(vo.getSecondChargeFlag());
entity.setIsCustom(vo.getIsCustom());
entity.setPayTime(new Date(Long.parseLong(vo.getDateTime())));
entity.setCreateTime(new Date());
entity.setUpdateTime(new Date());
return entity;
})
.collect(Collectors.toList());
stConsumptionExceptionRecordService.saveBatch(unselectedEntities);
}
/**
* 比较两个时间戳
*/
private int compareByDateTime(String dateTime1, String dateTime2) {
try {
long time1 = Long.parseLong(dateTime1);
long time2 = Long.parseLong(dateTime2);
return Long.compare(time1, time2);
} catch (Exception e) {
return 0;
}
}
/**
* 获取餐次类型
*/
private String getDinnerType(List<SlBaseDinnerTime> dinnerTimeList,String dateTime) {
try {
SlBaseDinnerTime dinnerTime = stBaseDinnerTimeService.getCanteenDinnerTypeByDateTime(dinnerTimeList, dateTime);
return dinnerTime != null ? dinnerTime.getDinnerType() : "UNKNOWN";
} catch (Exception e) {
return "UNKNOWN";
}
}
/**
* 食堂扣费主接口
*/
@Override @Override
public Result<StClientMemberSpendVO> bindUserOfflineCardCode(@RequestBody StRfidoffLineVo stRfidoffLineVo){ public Result<StClientMemberSpendVO> bindUserOfflineCardCode(StRfidoffLineVo stRfidoffLineVo,boolean onlineStatus) {
String deviceCode = stRfidoffLineVo.getDeviceCode(); String deviceCode = stRfidoffLineVo.getDeviceCode();
String restId = stRfidoffLineVo.getRestId(); String restId = stRfidoffLineVo.getRestId();
List<StRfidVo> voListAll = stRfidoffLineVo.getVoList(); List<StRfidVo> voListAll = stRfidoffLineVo.getVoList();
if(CollectionUtils.isEmpty(voListAll)){ if(CollectionUtils.isEmpty(voListAll)){
return Result.error("扣费信息不能为空"); return Result.error("扣费信息不能为空");
} }
voListAll.forEach(vo -> {
vo.setRestId(restId);
vo.setDeviceCode(deviceCode);
});
// //去重
// voListAll = filterDuplicateTimestamp(voListAll);
//数据预处理: 一人 一餐 除二次扣费外 只有一条扣费数据
voListAll = processUserMealDataSimplified(voListAll,restId);
Map<String, List<StRfidVo>> userListMaps = voListAll.stream().collect(Collectors.groupingBy(StRfidVo::getUserId));
for (Map.Entry<String, List<StRfidVo>> userListMap : userListMaps.entrySet()) {
String userId = userListMap.getKey();
List<StRfidVo> value = userListMap.getValue();
// 尝试获取锁,超时时间1分钟
String lockValue = redisLockUtil.tryLock(userId);
if (lockValue == null) {
return null;
}
try {
// //根据用户获取之后一次扣费时间
// Date maxTime = baseMapper.getMaxTimeByUserId(userId);
if(CollectionUtils.isEmpty(value)){
return Result.error("扣费信息不能为空");
}
//扣费规则(扣费类型(1:固定扣费,2:固定+补贴扣费,3:按量扣费,4:自定义金额)) //扣费规则(扣费类型(1:固定扣费,2:固定+补贴扣费,3:按量扣费,4:自定义金额))
StClientMemberLevelDeductRuleVo levelDeductRuleVo = this.getDeductRuleByCanteenId(restId); StClientMemberLevelDeductRuleVo levelDeductRuleVo = this.getDeductRuleByCanteenId(restId);
if(voListAll.size() > 1){//离线扣费 // //过滤时间小于1分钟的记录
// value = filterRecentThanOneMinute(value,maxTime.getTime());
if(!onlineStatus){//离线扣费
//加异步处理 //加异步处理
List<StRfidVo> finalVoListAll = value;
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
unifiedDeductionInterface(voListAll,restId,deviceCode,levelDeductRuleVo,false); unifiedDeductionInterface(finalVoListAll,restId,deviceCode,levelDeductRuleVo,false);
}); });
} else {//在线扣费 } else {//在线扣费
return unifiedDeductionInterface(voListAll,restId,deviceCode,levelDeductRuleVo,true); return unifiedDeductionInterface(value,restId,deviceCode,levelDeductRuleVo,true);
}
} catch (Exception e) {
e.printStackTrace();
return Result.error("扣费失败");
} finally {
//释放锁
redisLockUtil.releaseLock(userId, lockValue);
}
} }
return Result.OK("扣费成功"); return Result.OK("扣费成功");
} }
@@ -276,10 +492,39 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
Map<String, List<StRfidVo>> stringListMap = groupByMeal(voListAll, restId); Map<String, List<StRfidVo>> stringListMap = groupByMeal(voListAll, restId);
StMiniMineBalanceVo stMiniMineBalanceVoOnline = new StMiniMineBalanceVo(); StMiniMineBalanceVo stMiniMineBalanceVoOnline = new StMiniMineBalanceVo();
List<StRfidVo> unselectedData = new ArrayList<>();
List<StRfidVo> unselectedDataException = new ArrayList<>();
StRfidVo err = new StRfidVo();
for (Map.Entry<String, List<StRfidVo>> entry : stringListMap.entrySet()) { for (Map.Entry<String, List<StRfidVo>> entry : stringListMap.entrySet()) {
List<StRfidVo> voList = entry.getValue(); List<StRfidVo> voList = entry.getValue();
//数据排序: 防止 离线数据 一次正常扣费, 多次二次扣费, 导致数据添加有问题
voList.sort((o1, o2) ->
Long.compare(
Long.parseLong(o1.getDateTime()),
Long.parseLong(o2.getDateTime())
)
);
for (StRfidVo stRfidVo : voList) { // 改用普通for循环,方便控制流程 for (StRfidVo stRfidVo : voList) { // 改用普通for循环,方便控制流程
//判断用户本餐是否已经有数据
//二次扣费,自定义扣费, 不去判断用户是否有数据
System.out.println("二次扣费标记" + stRfidVo.getSecondChargeFlag());
if((stRfidVo.getSecondChargeFlag() == null || stRfidVo.getSecondChargeFlag() == 0) && (stRfidVo.getIsCustom() == null || stRfidVo.getIsCustom() == 0)){
long count = iStBbzxOrderInfoService.count(new LambdaQueryWrapper<StBbzxOrderInfo>()
.eq(StBbzxOrderInfo::getMemberId, stRfidVo.getUserId())
.eq(StBbzxOrderInfo::getDinnerType, entry.getKey())
.eq(StBbzxOrderInfo::getCanteenId, restId)
.eq(StBbzxOrderInfo::getStatus, 5)
.eq(StBbzxOrderInfo::getEatDay, DateUtils.formatDate(new Date(Long.parseLong(stRfidVo.getDateTime())), "yyyy-MM-dd"))
);
if(count > 0){
if(stRfidVo.getIsRestore() == null){
unselectedData.add(stRfidVo);
errorMessages = "本餐已扣费";
System.out.println("用户本餐已扣费");
continue;
}
}
}
stRfidVo.setDeviceCode(deviceCode); stRfidVo.setDeviceCode(deviceCode);
stRfidVo.setRestId(restId); stRfidVo.setRestId(restId);
if(!online){ if(!online){
@@ -299,24 +544,28 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
", 已存在的订单编号=" + stBbzxOrderInfo.getOrderNo(); ", 已存在的订单编号=" + stBbzxOrderInfo.getOrderNo();
log.error(errorMsg); log.error(errorMsg);
errorMessages = "重复支付"; // 添加错误信息 errorMessages = "重复支付"; // 添加错误信息
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; // 跳过当前循环,处理下一个 continue; // 跳过当前循环,处理下一个
} }
} }
// 当前餐次 // 当前餐次
String timesName = entry.getKey(); String timesName = entry.getKey();
System.out.println("当前餐次" + timesName);
BigDecimal rewardDeduction = BigDecimal.ZERO; BigDecimal rewardDeduction = BigDecimal.ZERO;
BigDecimal totalDeduction = BigDecimal.ZERO; BigDecimal totalDeduction = BigDecimal.ZERO;
Date dateTime = new Date(Long.parseLong(stRfidVo.getDateTime())); Date dateTime = new Date(Long.parseLong(stRfidVo.getDateTime()));
// 预算本次扣费金额 // 预算本次扣费金额
BigDecimal spendMoneyBudgeted = BigDecimal.ZERO; BigDecimal spendMoneyBudgeted = BigDecimal.ZERO;
BigDecimal moneyCustom = stRfidVo.getSpendMoney();
Integer deductionType; Integer deductionType;
if (moneyCustom != null && moneyCustom.compareTo(BigDecimal.ZERO) > 0) { Integer isCustom = stRfidVo.getIsCustom();
if (isCustom != null && isCustom == 1) {
// 自定义金额方式 // 自定义金额方式
spendMoneyBudgeted = moneyCustom; spendMoneyBudgeted = stRfidVo.getSpendMoney();
deductionType = 4; deductionType = 4;
} else { } else {
deductionType = 1; deductionType = 1;
@@ -329,6 +578,9 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
stRfidVo.getUserId(), null, null, 1, levelDeductRuleVo, stRfidVo.getUserId(), null, null, 1, levelDeductRuleVo,
errorMsg, stRfidVo)); errorMsg, stRfidVo));
} }
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
@@ -342,6 +594,9 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
String errorMsg = "计算预算扣费金额失败, userId=" + stRfidVo.getUserId() + ", 餐次=" + timesName; String errorMsg = "计算预算扣费金额失败, userId=" + stRfidVo.getUserId() + ", 餐次=" + timesName;
log.error(errorMsg, e); log.error(errorMsg, e);
errorMessages = "计算预算扣费金额失败"; errorMessages = "计算预算扣费金额失败";
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
} }
@@ -363,6 +618,9 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
stRfidVo.getUserId(), null, null, deductionType, stRfidVo.getUserId(), null, null, deductionType,
levelDeductRuleVo, errorMsg, stRfidVo)); levelDeductRuleVo, errorMsg, stRfidVo));
} }
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
stMiniMineBalanceVo = userBalanceResult.getResult(); stMiniMineBalanceVo = userBalanceResult.getResult();
@@ -378,6 +636,9 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
stRfidVo.getUserId(), null, null, deductionType, stRfidVo.getUserId(), null, null, deductionType,
levelDeductRuleVo, errorMsg, stRfidVo)); levelDeductRuleVo, errorMsg, stRfidVo));
} }
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
@@ -393,6 +654,9 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
stRfidVo.getUserId(), null, null, deductionType, levelDeductRuleVo, stRfidVo.getUserId(), null, null, deductionType, levelDeductRuleVo,
errorMsg, stRfidVo)); errorMsg, stRfidVo));
} }
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
@@ -405,6 +669,9 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
stRfidVo.getUserId(), null, null, deductionType, levelDeductRuleVo, stRfidVo.getUserId(), null, null, deductionType, levelDeductRuleVo,
finalErrorMessages +",卡号:"+ finalStMiniMineBalanceVo.getCardCode(), stRfidVo)); finalErrorMessages +",卡号:"+ finalStMiniMineBalanceVo.getCardCode(), stRfidVo));
} }
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
@@ -417,10 +684,16 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
if(online){ if(online){
if(stMiniMineBalanceVo.getUserStatus() != 1){ if(stMiniMineBalanceVo.getUserStatus() != 1){
errorMessages = "主用户已停用"; errorMessages = "主用户已停用";
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
if(stMiniMineBalanceVo.getStatus()!= 1){ if(stMiniMineBalanceVo.getStatus()!= 1){
errorMessages = "当前用户已停用"; errorMessages = "当前用户已停用";
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
} }
@@ -443,6 +716,9 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
String errorMsg = "自定义金额扣费操作失败, userId=" + userId + ", 错误信息: " + data; String errorMsg = "自定义金额扣费操作失败, userId=" + userId + ", 错误信息: " + data;
log.error(errorMsg); log.error(errorMsg);
errorMessages = "自定义金额扣费操作失败: " + data; errorMessages = "自定义金额扣费操作失败: " + data;
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
} else { } else {
@@ -459,6 +735,9 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
String errorMsg = "规则模式扣费操作失败, userId=" + userId + ", 错误信息: " + data; String errorMsg = "规则模式扣费操作失败, userId=" + userId + ", 错误信息: " + data;
log.error(errorMsg); log.error(errorMsg);
errorMessages = "规则模式扣费操作失败:" + data; errorMessages = "规则模式扣费操作失败:" + data;
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
} }
@@ -466,6 +745,9 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
String errorMsg = "扣费处理过程中发生异常, userId=" + userId + ", 异常信息: " + e.getMessage(); String errorMsg = "扣费处理过程中发生异常, userId=" + userId + ", 异常信息: " + e.getMessage();
log.error(errorMsg, e); log.error(errorMsg, e);
errorMessages = "扣费处理过程中发生异常: " + e.getMessage(); errorMessages = "扣费处理过程中发生异常: " + e.getMessage();
stRfidVo.setIsRestore(3);
stRfidVo.setErrorMsg(errorMessages);
unselectedDataException.add(stRfidVo);
continue; continue;
} }
@@ -478,6 +760,16 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
} }
} }
} }
//保存异常消费数据
if(CollectionUtils.isNotEmpty(unselectedData)){
saveExceptionRecord(unselectedData);
}
//余: 出异常的数据都存在 异常消费表中, 给特殊标记 不让恢复,展示异常原因
if(CollectionUtils.isNotEmpty(unselectedDataException)){
saveExceptionRecord(unselectedDataException);
}
if(online){//在线 if(online){//在线
// 根据错误信息返回不同结果 // 根据错误信息返回不同结果
if (StringUtils.isBlank(errorMessages)) { if (StringUtils.isBlank(errorMessages)) {
@@ -494,7 +786,11 @@ public class StClientMemberLevelDeductRuleServiceImpl extends JeecgServiceImpl<S
return Result.OK("扣费成功",stClientMemberSpendVO); return Result.OK("扣费成功",stClientMemberSpendVO);
} else { } else {
log.info("在线扣费耗时,error{}",System.currentTimeMillis() - start); log.info("在线扣费耗时,error{}",System.currentTimeMillis() - start);
if("本餐已扣费".equals(errorMessages)){
return Result.error(errorMessages); return Result.error(errorMessages);
}else {
return Result.error("扣费异常,请联系管理员");
}
} }
} }
return Result.OK("扣费成功"); return Result.OK("扣费成功");
@@ -1,15 +1,20 @@
package org.jeecg.payment.service.impl; package org.jeecg.payment.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.system.base.service.impl.JeecgServiceImpl; import org.jeecg.common.system.base.service.impl.JeecgServiceImpl;
import org.jeecg.payment.dto.StClientMemberTransactionRecordDTO; import org.jeecg.payment.dto.StClientMemberTransactionRecordDTO;
import org.jeecg.payment.entity.StBbzxOrderInfo;
import org.jeecg.payment.entity.StClientMemberBalance;
import org.jeecg.payment.entity.StClientMemberTransactionRecord; import org.jeecg.payment.entity.StClientMemberTransactionRecord;
import org.jeecg.payment.enums.MemberEnum; import org.jeecg.payment.enums.MemberEnum;
import org.jeecg.payment.enums.MemberTransactionTypeEnum; import org.jeecg.payment.enums.MemberTransactionTypeEnum;
import org.jeecg.payment.mapper.StClientMemberTransactionRecordMapper; import org.jeecg.payment.mapper.StClientMemberTransactionRecordMapper;
import org.jeecg.payment.service.IStBbzxOrderInfoService;
import org.jeecg.payment.service.IStClientMemberBalanceService;
import org.jeecg.payment.service.IStClientMemberTransactionRecordService; import org.jeecg.payment.service.IStClientMemberTransactionRecordService;
import org.jeecg.payment.vo.InOutRecordInfoVo; import org.jeecg.payment.vo.InOutRecordInfoVo;
import org.jeecg.payment.vo.StClientMemberTransactionRecordVO; import org.jeecg.payment.vo.StClientMemberTransactionRecordVO;
@@ -17,7 +22,13 @@ import org.jeecg.system.service.ISysPayDepartService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* 交易记录 * 交易记录
@@ -28,6 +39,10 @@ public class StClientMemberTransactionRecordServiceImpl extends JeecgServiceImpl
@Resource @Resource
private ISysPayDepartService iSysPayDepartService; private ISysPayDepartService iSysPayDepartService;
@Resource
private IStClientMemberBalanceService iStClientMemberBalanceService;
@Resource
private IStBbzxOrderInfoService iStBbzxOrderInfoService;
@Override @Override
public IPage<StClientMemberTransactionRecordVO> pageQuery(StClientMemberTransactionRecordDTO query) { public IPage<StClientMemberTransactionRecordVO> pageQuery(StClientMemberTransactionRecordDTO query) {
@@ -55,6 +70,61 @@ public class StClientMemberTransactionRecordServiceImpl extends JeecgServiceImpl
return page.setRecords(pageList); return page.setRecords(pageList);
} }
@Override
public IPage<StClientMemberTransactionRecordVO> pageQueryNew(StClientMemberTransactionRecordDTO query) {
Page<StClientMemberTransactionRecordVO> page = new Page<>(query.getPageNo(), query.getPageSize());
page.setSearchCount(false);
if(StringUtils.isNotBlank(query.getDepartId())){
List<String> allCascadeDeptIds = iSysPayDepartService.getAllCascadeDeptIds(query.getDepartId());
if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(allCascadeDeptIds)){
query.setList(allCascadeDeptIds);
}
}
//计算总数
long l = baseMapper.pageListCount(query);
page.setTotal(l);
page.setRecords(new ArrayList<>());
if(l > 0){
IPage<StClientMemberTransactionRecordVO> pageList = baseMapper.pageList2(page, query);
if(CollectionUtils.isNotEmpty(pageList.getRecords())){
Set<String> orderNoSet = pageList.getRecords().stream().map(StClientMemberTransactionRecordVO::getOrderNo).collect(Collectors.toSet());
Set<String> memberIdSet = pageList.getRecords().stream().map(StClientMemberTransactionRecordVO::getId).collect(Collectors.toSet());
Map<String, StBbzxOrderInfo> orderInfoMap = iStBbzxOrderInfoService.list(new LambdaQueryWrapper<StBbzxOrderInfo>().eq(StBbzxOrderInfo::getIsDel, 0).in(StBbzxOrderInfo::getOrderNo, orderNoSet))
.stream().collect(Collectors.toMap(StBbzxOrderInfo::getOrderNo,
Function.identity(),
(existing, replacement) -> existing));
Map<String, BigDecimal> balanceMap = iStClientMemberBalanceService.list(new LambdaQueryWrapper<StClientMemberBalance>().eq(StClientMemberBalance::getIsDel, 0).in(StClientMemberBalance::getMemberId, memberIdSet))
.stream().collect(Collectors.toMap(StClientMemberBalance::getMemberId,
StClientMemberBalance::getConsumptionTotal,
(existing, replacement) -> existing));
for (StClientMemberTransactionRecordVO record : pageList.getRecords()) {
StBbzxOrderInfo stBbzxOrderInfo = orderInfoMap.get(record.getOrderNo());
if(stBbzxOrderInfo != null){
record.setCardCode(stBbzxOrderInfo.getSerialNo());
record.setBusinessModel(stBbzxOrderInfo.getBusinessModel());
record.setDinnerType(stBbzxOrderInfo.getDinnerType());
record.setMonetary(balanceMap.get(record.getId()));
}
record.setStatusName(MemberTransactionTypeEnum.getName(record.getStatus()));
record.setPaymentMethodName(MemberEnum.getXcxName(record.getPaymentMethod()));
record.setUpdateStatusName(null != record.getUpdateStatus() && 1 == record.getUpdateStatus() ? "前端":"后台");
if(null != record.getBusinessModel()&& 1 == record.getBusinessModel() ){
record.setBusinessModelName("定值模式");//扣费类型(1:固定扣费,2:固定+补贴扣费,3:按量扣费,4:自定义金额)
}
if(null != record.getBusinessModel()&& 4 == record.getBusinessModel() ){
record.setBusinessModelName("金额模式");//扣费类型(1:固定扣费,2:固定+补贴扣费,3:按量扣费,4:自定义金额)
}
}
}
return pageList;
}
return page;
}
@Override @Override
public List<StClientMemberTransactionRecordVO> queryList(StClientMemberTransactionRecordDTO query) { public List<StClientMemberTransactionRecordVO> queryList(StClientMemberTransactionRecordDTO query) {
List<StClientMemberTransactionRecordVO> pageList = baseMapper.pageList(query); List<StClientMemberTransactionRecordVO> pageList = baseMapper.pageList(query);
@@ -74,6 +144,25 @@ public class StClientMemberTransactionRecordServiceImpl extends JeecgServiceImpl
return pageList; return pageList;
} }
@Override
public List<StClientMemberTransactionRecordVO> queryListNew(StClientMemberTransactionRecordDTO query) {
List<StClientMemberTransactionRecordVO> pageList = baseMapper.pageList2(query);
if (CollectionUtils.isNotEmpty(pageList)) {
for (StClientMemberTransactionRecordVO model : pageList) {
model.setStatusName(MemberTransactionTypeEnum.getName(model.getStatus()));
model.setPaymentMethodName(MemberEnum.getXcxName(model.getPaymentMethod()));
model.setUpdateStatusName(null != model.getUpdateStatus() && 1 == model.getUpdateStatus() ? "前端":"后台");
if(null != model.getBusinessModel()&& 1 == model.getBusinessModel() ){
model.setBusinessModelName("定值模式");//扣费类型(1:固定扣费,2:固定+补贴扣费,3:按量扣费,4:自定义金额)
}
if(null != model.getBusinessModel()&& 4 == model.getBusinessModel() ){
model.setBusinessModelName("金额模式");//扣费类型(1:固定扣费,2:固定+补贴扣费,3:按量扣费,4:自定义金额)
}
}
}
return pageList;
}
@Override @Override
public IPage<StClientMemberTransactionRecordVO> pageBalanceRefundList(Page<StClientMemberTransactionRecordVO> page,StClientMemberTransactionRecordDTO query) { public IPage<StClientMemberTransactionRecordVO> pageBalanceRefundList(Page<StClientMemberTransactionRecordVO> page,StClientMemberTransactionRecordDTO query) {
@@ -0,0 +1,166 @@
package org.jeecg.payment.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.ScreenVo;
import org.jeecg.payment.dto.StExceptionRecordDTO;
import org.jeecg.payment.entity.StConsumptionExceptionRecord;
import org.jeecg.payment.mapper.StConsumptionExceptionRecordMapper;
import org.jeecg.payment.service.IStConsumptionExceptionRecordService;
import org.jeecg.payment.vo.StExceptionRecordVo;
import org.jeecg.payment.vo.StRfidVo;
import org.jeecg.system.service.ISysPayDepartService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class StConsumptionExceptionRecordServiceImpl extends ServiceImpl<StConsumptionExceptionRecordMapper, StConsumptionExceptionRecord> implements IStConsumptionExceptionRecordService {
@Resource
private ISysPayDepartService iSysPayDepartService;
private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
@Override
public IPage<StExceptionRecordVo> exceptionRecordPage(StExceptionRecordDTO query){
//处理时间
if(CollectionUtils.isNotEmpty(query.getDates())){
query.setStartTime(query.getDates().get(0));
query.setEndTime(query.getDates().get(1));
}
if(StringUtils.isNotBlank(query.getDepartId())){
List<String> allCascadeDeptIds = iSysPayDepartService.getAllCascadeDeptIds(query.getDepartId());
if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(allCascadeDeptIds)){
query.setList(allCascadeDeptIds);
}
}
String canteenId = query.getCanteenId();
List<String> canteenIdList = new ArrayList<>();
if(StringUtils.isNotBlank(canteenId)){
canteenIdList.add(canteenId);
} else {
//权限校验
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<String> canteenIds = new ArrayList<>();
if(sysUser != null){
canteenIds = sysUser.getCanteenIdList().stream().map(ScreenVo::getId).collect(Collectors.toList());
canteenIdList.addAll(canteenIds);
}
}
query.setCanteenIdList(canteenIdList);
Page<StExceptionRecordVo> page = new Page<>(query.getPageNo(), query.getPageSize());
return baseMapper.exceptionRecordPage(page, query);
}
@Override
public List<StExceptionRecordVo> exceptionRecordPageExport(StExceptionRecordDTO query){
//处理时间
if(CollectionUtils.isNotEmpty(query.getDates())){
query.setStartTime(query.getDates().get(0));
query.setEndTime(query.getDates().get(1));
}
if(StringUtils.isNotBlank(query.getDepartId())){
List<String> allCascadeDeptIds = iSysPayDepartService.getAllCascadeDeptIds(query.getDepartId());
if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(allCascadeDeptIds)){
query.setList(allCascadeDeptIds);
}
}
String canteenId = query.getCanteenId();
List<String> canteenIdList = new ArrayList<>();
if(StringUtils.isNotBlank(canteenId)){
canteenIdList.add(canteenId);
} else {
//权限校验
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<String> canteenIds = new ArrayList<>();
if(sysUser != null){
canteenIds = sysUser.getCanteenIdList().stream().map(ScreenVo::getId).collect(Collectors.toList());
canteenIdList.addAll(canteenIds);
}
}
query.setCanteenIdList(canteenIdList);
return baseMapper.exceptionRecordPage(query);
}
/**
* 解析CSV文件到StRfidVo列表
* @param file 上传的CSV文件
* @param defaultDeviceCode 默认设备编码(必填字段)
* @param defaultRestId 默认食堂ID(必填字段)
* @return 解析后的对象列表
* @throws IOException 文件读取异常
*/
@Override
public List<StRfidVo> parse(MultipartFile file, String defaultDeviceCode, String defaultRestId) throws IOException {
// 检查文件类型
if (!file.getOriginalFilename().endsWith(".csv")) {
throw new IllegalArgumentException("仅支持CSV文件");
}
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) {
// 使用自定义映射策略
HeaderColumnNameMappingStrategy<StRfidVo> strategy = new HeaderColumnNameMappingStrategy<>();
strategy.setType(StRfidVo.class);
// 解析CSV
CsvToBean<StRfidVo> csvToBean = new CsvToBeanBuilder<StRfidVo>(reader)
.withMappingStrategy(strategy)
.withIgnoreLeadingWhiteSpace(true)
.withIgnoreEmptyLine(true)
.build();
List<StRfidVo> result = new ArrayList<>();
// 逐行处理并验证
csvToBean.forEach(vo -> {
// 设置必填字段
vo.setDeviceCode(defaultDeviceCode);
if (vo.getRestId() == null) {
vo.setRestId(defaultRestId);
}
// 验证对象
validateStRfidVo(vo);
result.add(vo);
});
return result;
}
}
private static void validateStRfidVo(StRfidVo vo) {
Set<ConstraintViolation<StRfidVo>> violations = validator.validate(vo);
if (!violations.isEmpty()) {
String errorMsg = violations.stream()
.map(v -> v.getPropertyPath() + " " + v.getMessage())
.collect(Collectors.joining(", "));
throw new IllegalArgumentException("数据验证失败: " + errorMsg);
}
}
}
@@ -55,5 +55,23 @@ public class StBaseRestaurantDeptController {
} }
} }
@Operation(summary = "获得食堂数据", description= "获得食堂数据")
@GetMapping(value = "/getAllRestaurantList")
public Result<?> getAllRestaurantList() {
List<ScreenVo> screenVoArrayList = new ArrayList<>();
List<SlBaseRestaurant> slBaseRestaurantList = slBaseRestaurantService.list();
if(CollectionUtils.isNotEmpty(slBaseRestaurantList)){
slBaseRestaurantList.forEach(slBaseRestaurant -> {
if(!"0".equals(slBaseRestaurant.getId())){
ScreenVo screenVo = new ScreenVo();
screenVo.setId(slBaseRestaurant.getId());
screenVo.setRestName(slBaseRestaurant.getRestName());
screenVoArrayList.add(screenVo);
}
});
}
return Result.OK(screenVoArrayList);
}
} }
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.restaurant.entity.SlBaseDinnerTime; import org.jeecg.restaurant.entity.SlBaseDinnerTime;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* @Description: 食堂餐次定义 * @Description: 食堂餐次定义
@@ -16,4 +17,12 @@ public interface ISlBaseDinnerTimeService extends IService<SlBaseDinnerTime> {
SlBaseDinnerTime getCanteenDinnerType(String canteenId, Date dataTime); SlBaseDinnerTime getCanteenDinnerType(String canteenId, Date dataTime);
SlBaseDinnerTime getCanteenDinnerType(String canteenId); SlBaseDinnerTime getCanteenDinnerType(String canteenId);
/**
* 根据时间戳获取对应餐次
* @param list 餐次列表(食堂对应已排序处理好的)
* @param dataTime 时间戳
* @return 对应餐次
*/
SlBaseDinnerTime getCanteenDinnerTypeByDateTime(List<SlBaseDinnerTime> list, String dataTime);
} }
@@ -5,11 +5,14 @@ import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.util.DateUtils; import org.jeecg.common.util.DateUtils;
import org.jeecg.restaurant.entity.SlBaseDinnerTime; import org.jeecg.restaurant.entity.SlBaseDinnerTime;
import org.jeecg.restaurant.mapper.SlBaseDinnerTimeMapper; import org.jeecg.restaurant.mapper.SlBaseDinnerTimeMapper;
import org.jeecg.restaurant.service.ISlBaseDinnerTimeService; import org.jeecg.restaurant.service.ISlBaseDinnerTimeService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.*;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@@ -61,4 +64,24 @@ public class SlBaseDinnerTimeServiceImpl extends ServiceImpl<SlBaseDinnerTimeMap
} }
return null; return null;
} }
@Override
public SlBaseDinnerTime getCanteenDinnerTypeByDateTime(List<SlBaseDinnerTime> list, String dataTime) {
for (SlBaseDinnerTime slBaseDinnerTime : list) {
DateTime endTime = DateUtil.parse(DateUtil.today() + " " + slBaseDinnerTime.getEndTime());
Date date = new Date();
if(StringUtils.isNotBlank(dataTime)){
long timestamp = Long.parseLong(dataTime);
date = new Date(timestamp);
endTime = DateUtil.parse(DateUtils.formatDate(date,"yyyy-MM-dd") + " " + slBaseDinnerTime.getEndTime());
}
if (DateUtil.compare(date, endTime) <= 0) {
return slBaseDinnerTime;
}
}
return list.get(list.size() - 1);
}
} }
@@ -149,6 +149,8 @@ public class SwUserFaceimgController extends JeecgController<SwUserFaceimg, ISwU
byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo); byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo);
slUserFaceimg.setFaceFeatureData(feature); slUserFaceimg.setFaceFeatureData(feature);
} }
} else {
return Result.error("人脸特征码提取失败!");
} }
slUserFaceimg.setFaceStatus("1"); slUserFaceimg.setFaceStatus("1");
slUserFaceimg.setUserId(userId); slUserFaceimg.setUserId(userId);
@@ -215,6 +217,8 @@ public class SwUserFaceimgController extends JeecgController<SwUserFaceimg, ISwU
byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo); byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo);
slUserFaceimg.setFaceFeatureData(feature); slUserFaceimg.setFaceFeatureData(feature);
} }
} else {
return Result.error("人脸特征码提取失败!");
} }
slUserFaceimg.setFaceStatus("1"); slUserFaceimg.setFaceStatus("1");
slUserFaceimg.setUserId(userId); slUserFaceimg.setUserId(userId);
@@ -285,6 +289,8 @@ public class SwUserFaceimgController extends JeecgController<SwUserFaceimg, ISwU
byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo); byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo);
slUserFaceimg.setFaceFeatureData(feature); slUserFaceimg.setFaceFeatureData(feature);
} }
} else {
return Result.error("人脸特征码提取失败!");
} }
slUserFaceimg.setFaceStatus("1"); slUserFaceimg.setFaceStatus("1");
slUserFaceimg.setUserId(userId); slUserFaceimg.setUserId(userId);
@@ -329,7 +335,7 @@ public class SwUserFaceimgController extends JeecgController<SwUserFaceimg, ISwU
*/ */
@GetMapping(value = "/updateAllUserFaceImg") @GetMapping(value = "/updateAllUserFaceImg")
public Result<String> updateAllUserFaceImg(@RequestParam(name = "type", required = false,defaultValue = "0") Integer type){ public Result<String> updateAllUserFaceImg(@RequestParam(name = "type", required = false,defaultValue = "0") Integer type){
return Result.OK(swUserFaceimgService.updateAllUserFaceImg(type)); return swUserFaceimgService.updateAllUserFaceImg(type);
} }
public Result<?> saveFaceImgSubLocalUpload(@RequestBody Map map) { public Result<?> saveFaceImgSubLocalUpload(@RequestBody Map map) {
@@ -361,6 +367,8 @@ public class SwUserFaceimgController extends JeecgController<SwUserFaceimg, ISwU
byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo); byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo);
slUserFaceimg.setFaceFeatureData(feature); slUserFaceimg.setFaceFeatureData(feature);
} }
}else{
return Result.error("人脸特征码提取失败!");
} }
slUserFaceimg.setFaceStatus("1"); slUserFaceimg.setFaceStatus("1");
slUserFaceimg.setUserId(userId); slUserFaceimg.setUserId(userId);
@@ -516,6 +524,8 @@ public class SwUserFaceimgController extends JeecgController<SwUserFaceimg, ISwU
byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo); byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo);
slUserFaceimg.setFaceFeatureData(feature); slUserFaceimg.setFaceFeatureData(feature);
} }
} else {
return Result.error("人脸特征码提取失败!");
} }
slUserFaceimg.setFaceStatus("1"); slUserFaceimg.setFaceStatus("1");
slUserFaceimg.setUserId(userId); slUserFaceimg.setUserId(userId);
@@ -9,10 +9,15 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.base.controller.JeecgController; import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.util.DateUtils; import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.equipment.entity.StCanteenEquipment;
import org.jeecg.equipment.service.IStCanteenEquipmentService;
import org.jeecg.system.service.IStUserFaceimgSubIncremInfoService; import org.jeecg.system.service.IStUserFaceimgSubIncremInfoService;
import org.jeecg.system.service.ISwUserFaceimgSubService; import org.jeecg.system.service.ISwUserFaceimgSubService;
import org.jeecg.system.vo.SwHeartbeatFaceVo;
import org.jeecg.user.entity.StUserFaceimgSubIncremInfo; import org.jeecg.user.entity.StUserFaceimgSubIncremInfo;
import org.jeecg.user.entity.SwUserFaceimgSub; import org.jeecg.user.entity.SwUserFaceimgSub;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -42,6 +47,10 @@ public class SwUserFaceimgSubController extends JeecgController<SwUserFaceimgSub
private ISwUserFaceimgSubService iSwUserFaceimgSubService; private ISwUserFaceimgSubService iSwUserFaceimgSubService;
@Resource @Resource
private IStUserFaceimgSubIncremInfoService iStUserFaceimgSubIncremInfoService; private IStUserFaceimgSubIncremInfoService iStUserFaceimgSubIncremInfoService;
@Resource
private IStCanteenEquipmentService stCanteenEquipmentService;
@Resource
private RedisUtil redisUtil;
/** /**
@@ -64,14 +73,37 @@ public class SwUserFaceimgSubController extends JeecgController<SwUserFaceimgSub
/** /**
* 扣费闸机心跳 * 扣费闸机心跳 设备大概30s调用一次(如需知道准确时间, 找设备确认)
* 1.人脸相关: 处理逻辑: 用户人脸新增后,会添加数据至st_user_faceimg_sub_increm_info表 , 通过设备上传时间戳 , 获取对应时间戳之后所有的增量人脸数据
* 2.在此心跳接口被调用时, 设备会发送设备本地数据: 设备ip, 设备人脸数, 设备剩余存储大小, 设备ip. 存到食堂设备关联表中
* 3.创建/更新redis中 设备的请求时间(根据心跳机制判断设备是否在线)
* 4.
*
* @param restId 食堂id
* @param qrcodeId 设备code(equipment_code)
* @param timeDate 毫秒级别时间戳
* @param faceNum 人脸数量(设备上)
* @param availableMemory 设备剩余存储大小
* @param ip 设备ip
* @return 增量人脸数据 List<StUserFaceimgSubIncremInfo>
*/ */
@Operation(summary = "扣费闸机心跳", description = "扣费闸机心跳") @Operation(summary = "扣费闸机心跳", description = "扣费闸机心跳")
@GetMapping("/heartbeat/interface") @GetMapping("/heartbeat/interface")
@AutoLog(value = "扣费闸机心跳") @AutoLog(value = "扣费闸机心跳")
public Result heartbeatInterface(@RequestParam(name = "restId", required = false) String restId, public Result heartbeatInterface(@RequestParam(name = "restId", required = false) String restId,
@RequestParam(name = "qrcodeId", required = false) String qrcodeId, @RequestParam(name = "qrcodeId", required = false) String qrcodeId,
@RequestParam(name = "timeDate", required = false) String timeDate) { @RequestParam(name = "timeDate", required = false) String timeDate,
@RequestParam(name = "faceNum", required = false) Integer faceNum,
@RequestParam(name = "availableMemory", required = false) String availableMemory,
@RequestParam(name = "ip", required = false) String ip) {
SwHeartbeatFaceVo vo = new SwHeartbeatFaceVo();
vo.setIssue(false);
Object hget = redisUtil.hget(CommonConstant.ISSUE_INFORMATION, qrcodeId);
if(hget != null){
vo.setIssue(true);
//删除下发指令标记
redisUtil.hdel(CommonConstant.ISSUE_INFORMATION, qrcodeId);
}
if(StringUtils.isNotBlank(timeDate)){ if(StringUtils.isNotBlank(timeDate)){
LambdaQueryWrapper<StUserFaceimgSubIncremInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<StUserFaceimgSubIncremInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
Date date = new Date(Long.parseLong(timeDate)); Date date = new Date(Long.parseLong(timeDate));
@@ -81,9 +113,21 @@ public class SwUserFaceimgSubController extends JeecgController<SwUserFaceimgSub
// 按 createTime 降序排列,获取最新数据 // 按 createTime 降序排列,获取最新数据
lambdaQueryWrapper.orderByDesc(StUserFaceimgSubIncremInfo::getCreateTime); lambdaQueryWrapper.orderByDesc(StUserFaceimgSubIncremInfo::getCreateTime);
List<StUserFaceimgSubIncremInfo> list = iStUserFaceimgSubIncremInfoService.list(lambdaQueryWrapper); List<StUserFaceimgSubIncremInfo> list = iStUserFaceimgSubIncremInfoService.list(lambdaQueryWrapper);
return Result.OK(list);
// 保存食堂设备关联表
StCanteenEquipment stCanteenEquipment = new StCanteenEquipment();
stCanteenEquipment.setEquipmentCode(qrcodeId);
stCanteenEquipment.setCanteenId(restId);
stCanteenEquipment.setEquipmentIp(ip);
stCanteenEquipment.setFaceNum(faceNum);
stCanteenEquipment.setAvailableMemory(availableMemory);
stCanteenEquipmentService.saveOrUpdate(stCanteenEquipment);
redisUtil.hset(CommonConstant.DEVICE_STATUS, qrcodeId, timeDate);
vo.setFaceList(list);
return Result.OK(vo);
} }
return Result.OK(Collections.emptyList()); return Result.OK(vo);
} }
} }
@@ -46,5 +46,5 @@ public interface ISwUserFaceimgService extends IService<SwUserFaceimg> {
*/ */
void sendPaymentGateUserInfo(UserFaceInfo userFaceInfo, Integer type, Boolean isConfirm, String userId) ; void sendPaymentGateUserInfo(UserFaceInfo userFaceInfo, Integer type, Boolean isConfirm, String userId) ;
String updateAllUserFaceImg(Integer type); Result<String> updateAllUserFaceImg(Integer type);
} }
@@ -20,7 +20,7 @@ public interface ISysUserSubService extends IService<SysUserSub> {
* innerUser = true 表示内部用户 * innerUser = true 表示内部用户
* innerUser = false 表示外部用户 * innerUser = false 表示外部用户
*/ */
public void initializeUserWallet(List<String> memberId,Boolean innerUser); public void initializeUserWallet(List<String> memberId,Integer userType);
/** /**
* 删除用户 * 删除用户
* @param userId * @param userId
@@ -307,6 +307,8 @@ public class SwUserFaceimgServiceImpl extends ServiceImpl<SwUserFaceimgMapper, S
byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo); byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo);
slUserFaceimg.setFaceFeatureData(feature); slUserFaceimg.setFaceFeatureData(feature);
} }
} else {
continue;
} }
slUserFaceimg.setFaceStatus("1"); slUserFaceimg.setFaceStatus("1");
slUserFaceimg.setCardNumber(cardNo); slUserFaceimg.setCardNumber(cardNo);
@@ -411,7 +413,7 @@ public class SwUserFaceimgServiceImpl extends ServiceImpl<SwUserFaceimgMapper, S
} }
//此方法是为了更新人脸特征数据 , 因为初始化数据 进去的人脸特征识别有问题, 现通过程序重新识别生成特征码并更新 //此方法是为了更新人脸特征数据 , 因为初始化数据 进去的人脸特征识别有问题, 现通过程序重新识别生成特征码并更新
@Override @Override
public String updateAllUserFaceImg(Integer type){ public Result<String> updateAllUserFaceImg(Integer type){
if(type == 1){ if(type == 1){
//正式员工人脸表 //正式员工人脸表
@@ -436,11 +438,13 @@ public class SwUserFaceimgServiceImpl extends ServiceImpl<SwUserFaceimgMapper, S
byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo); byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo);
swUserFaceimg.setFaceFeatureData(feature); swUserFaceimg.setFaceFeatureData(feature);
} }
} else {
return Result.error("人脸特征码提取失败!");
} }
} }
this.updateBatchById(list); this.updateBatchById(list);
} }
return "此次操作更新人脸主表数据"+ list.size()+"条数据"; return Result.OK("此次操作更新人脸主表数据"+ list.size()+"条数据");
}else { }else {
//子用户 //子用户
//正式员工人脸表 //正式员工人脸表
@@ -464,11 +468,13 @@ public class SwUserFaceimgServiceImpl extends ServiceImpl<SwUserFaceimgMapper, S
byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo); byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfo);
faceimgSub.setFaceFeatureData(feature); faceimgSub.setFaceFeatureData(feature);
} }
} else {
return Result.error("人脸特征码提取失败!");
} }
} }
swUserFaceimgSubService.updateBatchById(subList); swUserFaceimgSubService.updateBatchById(subList);
} }
return "此次操作更新人脸子表数据"+subList.size()+"条数据"; return Result.OK("此次操作更新人脸子表数据"+subList.size()+"条数据");
} }
} }
} }
@@ -18,6 +18,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
/** /**
* <p> * <p>
@@ -39,48 +40,82 @@ public class SysPayDepartServiceImpl extends ServiceImpl<SysPayDepartMapper, Sys
*/ */
@Override @Override
public List<String> getAllCascadeDeptIds(String deptId) { public List<String> getAllCascadeDeptIds(String deptId) {
List<String> allDeptIds = new ArrayList<>();
if (deptId == null) { if (deptId == null) {
return allDeptIds; return Collections.emptyList();
}
// 从目标部门开始递归查询
recursiveQueryDeptIds(deptId, allDeptIds);
return allDeptIds;
} }
/** // 1. 一次性查询所有有效部门
* 递归查询部门ID及其所有子部门ID List<SysPayDepart> allDepts = this.list(new LambdaQueryWrapper<SysPayDepart>()
* @param deptId 当前部门ID
* @param result 用于收集结果的集合
*/
private void recursiveQueryDeptIds(String deptId, List<String> result) {
// 1. 先查询当前部门信息并添加到结果集(去重)
if (!result.contains(deptId)) {
// 验证当前部门是否存在且有效
SysPayDepart currentDept = this.getOne(new LambdaQueryWrapper<SysPayDepart>()
.eq(SysPayDepart::getId, deptId)
.eq(SysPayDepart::getDelFlag, "0")); .eq(SysPayDepart::getDelFlag, "0"));
if (currentDept != null) { // 2. 构建部门父子关系Map
result.add(deptId); Map<String, List<String>> parentToChildrenMap = allDepts.stream()
} else { .collect(Collectors.groupingBy(
// 当前部门不存在或已删除,终止递归 SysPayDepart::getParentId,
return; Collectors.mapping(SysPayDepart::getId, Collectors.toList())
} ));
// 3. 在内存中递归查找
List<String> result = new ArrayList<>();
recursiveFindDeptIds(deptId, parentToChildrenMap, result);
return result;
} }
// 2. 查询当前部门的直接子部门 private void recursiveFindDeptIds(String currentDeptId,
List<SysPayDepart> childDepts = this.list(new LambdaQueryWrapper<SysPayDepart>() Map<String, List<String>> parentToChildrenMap,
.eq(SysPayDepart::getParentId, deptId) List<String> result) {
.eq(SysPayDepart::getDelFlag, "0")); result.add(currentDeptId);
List<String> children = parentToChildrenMap.get(currentDeptId);
// 3. 对每个子部门递归查询其下属部门 if (children != null) {
for (SysPayDepart child : childDepts) { for (String childId : children) {
String childId = child.getId(); recursiveFindDeptIds(childId, parentToChildrenMap, result);
// 递归处理子部门,会自动添加子部门及其下级
recursiveQueryDeptIds(childId, result);
} }
} }
}
//
// public List<String> getAllCascadeDeptIds(String deptId) {
// List<String> allDeptIds = new ArrayList<>();
// if (deptId == null) {
// return allDeptIds;
// }
// // 从目标部门开始递归查询
// recursiveQueryDeptIds(deptId, allDeptIds);
// return allDeptIds;
// }
//
// /**
// * 递归查询部门ID及其所有子部门ID
// * @param deptId 当前部门ID
// * @param result 用于收集结果的集合
// */
// private void recursiveQueryDeptIds(String deptId, List<String> result) {
// // 1. 先查询当前部门信息并添加到结果集(去重)
// if (!result.contains(deptId)) {
// // 验证当前部门是否存在且有效
// SysPayDepart currentDept = this.getOne(new LambdaQueryWrapper<SysPayDepart>()
// .eq(SysPayDepart::getId, deptId)
// .eq(SysPayDepart::getDelFlag, "0"));
//
// if (currentDept != null) {
// result.add(deptId);
// } else {
// // 当前部门不存在或已删除,终止递归
// return;
// }
// }
//
// // 2. 查询当前部门的直接子部门
// List<SysPayDepart> childDepts = this.list(new LambdaQueryWrapper<SysPayDepart>()
// .eq(SysPayDepart::getParentId, deptId)
// .eq(SysPayDepart::getDelFlag, "0"));
//
// // 3. 对每个子部门递归查询其下属部门
// for (SysPayDepart child : childDepts) {
// String childId = child.getId();
// // 递归处理子部门,会自动添加子部门及其下级
// recursiveQueryDeptIds(childId, result);
// }
// }
/** /**
@@ -68,7 +68,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
sysUserSubMapper.insert(user); sysUserSubMapper.insert(user);
if(2 != user.getUserType()){//只有正式员工、非正式员工才创建钱包 if(2 != user.getUserType()){//只有正式员工、非正式员工才创建钱包
//创建钱包 //创建钱包
iSysUserSubService.initializeUserWallet(Collections.singletonList(user.getId()),false); iSysUserSubService.initializeUserWallet(Collections.singletonList(user.getId()),user.getUserType());
} }
return Result.OK(); return Result.OK();
} }
@@ -42,7 +42,7 @@ public class SysUserSubServiceImpl extends ServiceImpl<SysUserSubMapper, SysUser
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void initializeUserWallet(List<String> memberIds,Boolean innerUser) { public void initializeUserWallet(List<String> memberIds,Integer userType) {
if(CollectionUtil.isNotEmpty(memberIds)){ if(CollectionUtil.isNotEmpty(memberIds)){
memberIds.forEach(memberId->{ memberIds.forEach(memberId->{
// 根据 memberId 查询用户数据 // 根据 memberId 查询用户数据
@@ -61,11 +61,7 @@ public class SysUserSubServiceImpl extends ServiceImpl<SysUserSubMapper, SysUser
newBalance.setLastConsumptionTime(null); newBalance.setLastConsumptionTime(null);
newBalance.setFirstTopUpTime(null); newBalance.setFirstTopUpTime(null);
newBalance.setInvoiceTotal(BigDecimal.ZERO); newBalance.setInvoiceTotal(BigDecimal.ZERO);
if(innerUser){ newBalance.setUserInnerType(userType);
newBalance.setUserInnerType(0); // 默认内部用户
} else {
newBalance.setUserInnerType(1); // 默认外部用户
}
newBalance.setIsDel(0); // 默认未删除 newBalance.setIsDel(0); // 默认未删除
newBalance.setIsStatus(0); newBalance.setIsStatus(0);
newBalance.setCreateBy("system"); // 默认创建人 newBalance.setCreateBy("system"); // 默认创建人
@@ -97,7 +97,7 @@ spring:
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000 connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource: datasource:
master: master:
url: jdbc:mysql://10.59.235.137:3306/zhst_finance?Unicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai url: jdbc:mysql://10.59.235.137:3306/zhst_finance_new?Unicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root username: root
password: 123qwe!@#P@ssw0rd password: 123qwe!@#P@ssw0rd
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
@@ -289,9 +289,9 @@ third-app:
# 虹软人脸识别(WIN和UNIX的sdkKey不一致,需要切换) 激活码需要配置 # 虹软人脸识别(WIN和UNIX的sdkKey不一致,需要切换) 激活码需要配置
face: face:
# windows # windows
appId: 3RX8bPDaEx3ZLYrxKEZ9F8hT5cqTma49AoeQhTMW8Wvg appId: 5fiiFa6fTSRhDbiarBSMGVS1hEkDyMQLYyBgn97EzZyb
sdkKey: CsNxFiPekJAyuQRjwY3c918ARVEEyCyzuvmMwWDUAjsF sdkKey: 3QndXfNCsoUM5hDyzSw2a3j7Ke3eL4J9by1yKfUsQJSC
activeKey: 86L1-11ZG-412Q-XKLB activeKey: 86L1-11Z4-61B4-AEQ1
libPath: ./facelib libPath: ./facelib
detect: detect:
pool: pool: