diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java index bc4c7e57..2e3c8f56 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java @@ -86,7 +86,7 @@ public interface ErrorCodeConstants { ErrorCode EXIST_TO_COMPLETE_ORDER = new ErrorCode(1_004_099_008, "存在未支付完的订单"); ErrorCode CARD_ALREADY_BIND = new ErrorCode(1_004_099_008, "卡号已绑定"); ErrorCode ORDER_NOT_COMPLETE = new ErrorCode(1_004_099_009, "订单未完成"); - ErrorCode NEED_ADD_USER = new ErrorCode(1_007_901_004, "请先添加人员"); + ErrorCode NEED_ADD_USER = new ErrorCode(1_007_901_004, "人员未指定"); ErrorCode ADMIN_CARD_NOT_EXISTS = new ErrorCode(1_007_901_005, "管理员卡不存在"); ErrorCode CARD_NOT_EXIST = new ErrorCode(1_007_901_005, "卡号不存在"); ErrorCode ADMIN_CARD = new ErrorCode(1_007_901_006, "管理员餐盘无法绑定"); diff --git a/yudao-module-member/yudao-module-member-biz/pom.xml b/yudao-module-member/yudao-module-member-biz/pom.xml index 5ea21262..8a299144 100644 --- a/yudao-module-member/yudao-module-member-biz/pom.xml +++ b/yudao-module-member/yudao-module-member-biz/pom.xml @@ -94,6 +94,19 @@ yudao-spring-boot-starter-websocket + + + com.google.zxing + core + 3.4.1 + + + com.google.zxing + javase + 3.4.1 + + + diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/business/vo/BusinessPageReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/business/vo/BusinessPageReqVO.java index 3149fa93..71afcfa9 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/business/vo/BusinessPageReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/business/vo/BusinessPageReqVO.java @@ -49,7 +49,7 @@ public class BusinessPageReqVO extends PageParam { @Schema(description = "智能称重") private BigDecimal weigh; - @Schema(description = "创建时间") + @Schema(description = "日期") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/business/vo/BusinessRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/business/vo/BusinessRespVO.java index 9d6915e7..344b8a9d 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/business/vo/BusinessRespVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/business/vo/BusinessRespVO.java @@ -73,4 +73,12 @@ public class BusinessRespVO { private BigDecimal withdrawal; private BigDecimal reduce; + + private String time; + + private BigDecimal turnoverCompare; + + private int orderSumCompare; + + private BigDecimal priceAvgCompare; } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/business/AppBusinessController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/business/AppBusinessController.java new file mode 100644 index 00000000..97313b12 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/business/AppBusinessController.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.member.controller.app.business; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.member.controller.admin.business.vo.BusinessRespVO; +import cn.iocoder.yudao.module.member.controller.app.business.vo.BusinessDataVO; +import cn.iocoder.yudao.module.member.dal.dataobject.business.BusinessDO; +import cn.iocoder.yudao.module.member.service.business.BusinessService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import java.util.ArrayList; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + + +@Tag(name = "管理后台 - 营业统计") +@RestController +@RequestMapping("/t/business") +@Validated +public class AppBusinessController { + + @Resource + private BusinessService businessService; + + + + @GetMapping("/data") + @Operation(summary = "获得营业统计") + public CommonResult getBusinessPage(String time,Long carteenId,Integer type) { + BusinessDataVO result = new BusinessDataVO(); + switch (type){ + case 0: + result = businessService.getDay(time, carteenId); + break; + case 1: + result = businessService.getWeek(time, carteenId); + break; + case 2: + result = businessService.getMonth(time, carteenId); + break; + default: + break; + } + + return success(result); + } +} \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/business/vo/BusinessDataVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/business/vo/BusinessDataVO.java new file mode 100644 index 00000000..f74def83 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/business/vo/BusinessDataVO.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.member.controller.app.business.vo; + + +import cn.iocoder.yudao.module.member.controller.admin.business.vo.BusinessRespVO; +import lombok.Data; + +import java.util.List; + +@Data +public class BusinessDataVO { + + private BusinessRespVO old; + private List businessList; + + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/store/AppStoreController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/store/AppStoreController.java index 14369354..e1bb923c 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/store/AppStoreController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/store/AppStoreController.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.member.controller.app.store; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.StoreResult; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -173,6 +174,21 @@ public class AppStoreController { return JsonUtils.toJsonString(StoreResult.success(null)); } + + + @PostMapping("/mgcr/order/payByCodeOrder") + @Operation(summary = "添加二维码订单") + public String payByCodeOrder(@RequestBody StoreOrderDto dto) { + + String s = orderService.codePay(dto); + + if(StrUtil.isNotBlank(s)){ + return JsonUtils.toJsonString(StoreResult.fail(s)); + }else { + return JsonUtils.toJsonString(StoreResult.success(null)); + } + } + public String reverseHexAndConvert(String hexStr) { // 将十六进制字符串反转,每两位一组 StringBuilder reversedHex = new StringBuilder(); @@ -191,4 +207,9 @@ public class AppStoreController { return decimalStr; } + + + + + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/store/dto/StoreOrderDto.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/store/dto/StoreOrderDto.java index d7593c64..f8b65877 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/store/dto/StoreOrderDto.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/store/dto/StoreOrderDto.java @@ -6,4 +6,6 @@ import lombok.Data; public class StoreOrderDto extends StoreSaleGoodsDto{ private String cardNumber; + + private String jwt; } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java index 858fbd97..bfe43ef1 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java @@ -151,5 +151,11 @@ public class AppMemberUserController { public CommonResult> getInfoByCard(String cardId,Long mobile){ return success(userService.getInfoByCard(cardId,mobile)); } + + @GetMapping("/getQRCode") + @Operation(summary = "获取消费二维码") + public CommonResult getQRCode(){ + return success(userService.getQRCode()); + } } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/storeorderdetail/StoreOrderDetailDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/storeorderdetail/StoreOrderDetailDO.java index a50bc0e9..91b07cac 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/storeorderdetail/StoreOrderDetailDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/storeorderdetail/StoreOrderDetailDO.java @@ -44,4 +44,9 @@ public class StoreOrderDetailDO extends BaseDO { */ private Integer number; + /** + * 重量 + */ + private Double weight; + } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/AmountService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/AmountService.java new file mode 100644 index 00000000..3a89fc20 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/AmountService.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.member.service.amount; + +import java.math.BigDecimal; + +public interface AmountService { + + + void operateAmount(Long userId, BigDecimal money, BigDecimal cashAmount, BigDecimal giftAmount, BigDecimal wxAmount); + + BigDecimal getAmount(Long userId); + + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/AmountServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/AmountServiceImpl.java new file mode 100644 index 00000000..1b3985e2 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/AmountServiceImpl.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.member.service.amount; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.member.dal.dataobject.card.CardDO; +import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO; +import cn.iocoder.yudao.module.member.dal.dataobject.rechargelog.RechargeLogDO; +import cn.iocoder.yudao.module.member.dal.dataobject.refund.RefundDO; +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; +import cn.iocoder.yudao.module.member.dal.mysql.card.CardMapper; +import cn.iocoder.yudao.module.member.dal.mysql.order.DishOrderMapper; +import cn.iocoder.yudao.module.member.dal.mysql.rechargelog.RechargeLogMapper; +import cn.iocoder.yudao.module.member.dal.mysql.refund.IntegralRefundMapper; +import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; +import cn.iocoder.yudao.module.member.enums.CostTypeEnum; +import cn.iocoder.yudao.module.member.service.appup.AppUpService; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * 金额操作 Service 实现类 + * + * @author 开发账号 + */ + +@Service +@Slf4j +public class AmountServiceImpl implements AmountService { + + @Resource + private MemberUserMapper userMapper; + @Resource + private DishOrderMapper dishOrderMapper; + @Resource + private CardMapper cardMapper; + @Resource + private IntegralRefundMapper refundMapper; + @Resource + private RechargeLogMapper rechargeLogMapper; + + @Override + public void operateAmount(Long userId, BigDecimal money, BigDecimal cashAmount, BigDecimal giftAmount, BigDecimal wxAmount) { + synchronized (userId) { + MemberUserDO memberUserDO = userMapper.selectById(userId); + if (memberUserDO != null) { + memberUserDO.setMoney(memberUserDO.getMoney().add(money)); + memberUserDO.setCashAmount(memberUserDO.getCashAmount().add(cashAmount)); + memberUserDO.setGiftAmount(memberUserDO.getGiftAmount().add(giftAmount)); +// memberUserDO.setWxAmt(memberUserDO.getWxAmt().add(wxAmount)); + userMapper.updateById(memberUserDO); + } + } + } + + @Override + public BigDecimal getAmount(Long userId) { + MemberUserDO memberUserDO = userMapper.selectById(userId); + return memberUserDO.getMoney(); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/CashRechargeService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/CashRechargeService.java new file mode 100644 index 00000000..b8a02889 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/CashRechargeService.java @@ -0,0 +1,12 @@ +package cn.iocoder.yudao.module.member.service.amount; + +import cn.iocoder.yudao.module.member.controller.admin.card.vo.RechargeVO; + +import java.math.BigDecimal; +import java.util.List; + +public interface CashRechargeService { + + + void rechargeByAdmin(List userIds, Long groupId, BigDecimal money); +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/CashRechargeServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/CashRechargeServiceImpl.java new file mode 100644 index 00000000..98ef0d7e --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/CashRechargeServiceImpl.java @@ -0,0 +1,154 @@ +package cn.iocoder.yudao.module.member.service.amount; + + +import cn.hutool.core.collection.CollectionUtil; +import cn.iocoder.yudao.module.member.dal.dataobject.card.CardDO; +import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO; +import cn.iocoder.yudao.module.member.dal.dataobject.refund.RefundDO; +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; +import cn.iocoder.yudao.module.member.dal.mysql.card.CardMapper; +import cn.iocoder.yudao.module.member.dal.mysql.group.MemberGroupMapper; +import cn.iocoder.yudao.module.member.dal.mysql.order.DishOrderMapper; +import cn.iocoder.yudao.module.member.dal.mysql.refund.IntegralRefundMapper; +import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; +import cn.iocoder.yudao.module.member.enums.CostTypeEnum; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 现金充值 Service 实现类 + * + * @author 开发账号 + */ +@Service +@Slf4j +public class CashRechargeServiceImpl implements CashRechargeService{ + + @Resource + private MemberUserMapper userMapper; + @Resource + private DishOrderMapper dishOrderMapper; + @Resource + private CardMapper cardMapper; + @Resource + private IntegralRefundMapper refundMapper; + @Resource + private MemberGroupMapper memberGroupMapper; + + + @Override + public void rechargeByAdmin(List userIds, Long groupId, BigDecimal money) { + List memberList = new ArrayList<>(); + if (groupId != null) { + memberList.addAll(memberGroupMapper.getMemberList(groupId)); + } else { + memberList.addAll(userIds); + } + //明细列表 + ArrayList addList = new ArrayList<>(); + + for (Long userId : memberList){ + + BigDecimal newMoney; + BigDecimal wxNewMoney; + BigDecimal giftNewMoney; + BigDecimal cashNewAmount; + + synchronized (userId){ + MemberUserDO memberUserDO = userMapper.selectById(userId); + //金额变动 + memberUserDO.setMoney(memberUserDO.getMoney().add(money)); + if (memberUserDO.getMoney().compareTo(BigDecimal.ZERO) > 0) { + memberUserDO.setCashAmount(memberUserDO.getCashAmount().add(money)); + } + userMapper.updateById(memberUserDO); + + newMoney = memberUserDO.getMoney(); + wxNewMoney = memberUserDO.getWxAmount(); + giftNewMoney = memberUserDO.getGiftAmount(); + cashNewAmount = memberUserDO.getCashAmount(); + } + + //记录明细 + CardDO add = new CardDO(); + add.setUserId(userId); + add.setFlag(CardDO.ADD); + add.setChangeMoney(money); + add.setType(CostTypeEnum.ADMIN_PAY.getCode()); + add.setMoney(newMoney); + add.setCashAmount(cashNewAmount); + add.setWxAmount(wxNewMoney); + add.setGiftAmount(giftNewMoney); + addList.add(add); + + } + + //处理订单 + handleOrderCash(memberList,money); + + //批量添加 + cardMapper.insertBatch(addList); + } + + + void handleOrderCash(List userIds, BigDecimal money) { + ArrayList updateList = new ArrayList<>(); + List refundOrder = getRefundOrder(); + //查询出所有未完全支付订单 + for (Long userId : userIds){ + BigDecimal cashMoney = money; + + List dishOrderDOS = dishOrderMapper.selectList(Wrappers.lambdaQuery() + .eq(DishOrderDO::getUserId, userId).eq(DishOrderDO::getOrderStatus, DishOrderDO.TOCOMPLETE)); + + if (CollectionUtil.isNotEmpty(dishOrderDOS)) { + for (DishOrderDO dishOrderDO : dishOrderDOS) { + BigDecimal payAmount = dishOrderDO.getPayAmount(); + if(payAmount.compareTo(cashMoney)<=0){ + dishOrderDO.setOrderStatus(DishOrderDO.COMPLETE); + dishOrderDO.setPayAmount(BigDecimal.ZERO); + dishOrderDO.setRefundAmount(dishOrderDO.getRefundAmount().add(payAmount)); + if(refundOrder.contains(dishOrderDO.getId())){ + dishOrderDO.setRefundAmount(BigDecimal.ZERO); + } + dishOrderDO.setCashAmount(dishOrderDO.getCashAmount().add(payAmount)); + cashMoney = cashMoney.subtract(payAmount); + updateList.add(dishOrderDO); + }else { + dishOrderDO.setPayAmount(payAmount.subtract(cashMoney)); + dishOrderDO.setRefundAmount(dishOrderDO.getRefundAmount().add(cashMoney)); + if(refundOrder.contains(dishOrderDO.getId())){ + dishOrderDO.setRefundAmount(BigDecimal.ZERO); + } + dishOrderDO.setCashAmount(dishOrderDO.getCashAmount().add(cashMoney)); + updateList.add(dishOrderDO); + break; + } + } + } + } + if(CollectionUtil.isNotEmpty(updateList)){ + dishOrderMapper.updateBatch(updateList); + } + + } + + public List getRefundOrder(){ + List refundDOS = refundMapper.selectList(Wrappers.lambdaQuery().in(RefundDO::getStatus, Arrays.asList("2", "3"))); + ArrayList orderIds = new ArrayList<>(); + if(CollectionUtil.isNotEmpty(refundDOS)){ + List collect = refundDOS.stream().map(RefundDO::getOrderId).collect(Collectors.toList()); + orderIds.addAll(collect); + } + + return orderIds; + } +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/DeductionService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/DeductionService.java new file mode 100644 index 00000000..24e06653 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/DeductionService.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.member.service.amount; + +import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO; + +import java.math.BigDecimal; +import java.util.List; + +public interface DeductionService { + + /** + * 餐盘扣减余额 + */ + DishOrderDO deduction(DishOrderDO dishOrderDO); + + /** + * 现金提现 + */ + void cashDraw(Long userId, BigDecimal money); + + /** + * 微信提现 + */ + void wxDraw(Integer amount, Long userId); +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/DeductionServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/DeductionServiceImpl.java new file mode 100644 index 00000000..480b0c9c --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/DeductionServiceImpl.java @@ -0,0 +1,251 @@ +package cn.iocoder.yudao.module.member.service.amount; + + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.member.controller.admin.business.vo.StatisticsVo; +import cn.iocoder.yudao.module.member.dal.dataobject.card.CardDO; +import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO; +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; +import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; +import cn.iocoder.yudao.module.member.enums.CostTypeEnum; +import cn.iocoder.yudao.module.member.enums.TimePeriodEnum; +import cn.iocoder.yudao.module.member.service.business.BusinessService; +import cn.iocoder.yudao.module.member.service.card.CardService; +import cn.iocoder.yudao.module.member.service.diningplates.DiningPlatesService; +import cn.iocoder.yudao.module.member.service.order.OrderService; +import cn.iocoder.yudao.module.member.service.user.MemberUserService; +import cn.iocoder.yudao.module.member.util.MemberConstants; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.CASH_AMOUNT_NOT_ENOUGH; + + +/** + * 餐盘统一扣款 Service 实现类 + * + * @author 开发账号 + */ + +@Service +@Slf4j +public class DeductionServiceImpl implements DeductionService { + + @Resource + private StringRedisTemplate deductionRedisTemplate; + @Resource + private CardService cardService; + @Resource + private MemberUserService userService; + @Resource + private BusinessService businessService; + + @Override + public DishOrderDO deduction(DishOrderDO dishOrderDO) { + Long userId = dishOrderDO.getUserId(); + + BigDecimal newMoney; + BigDecimal changeMoney; + BigDecimal wxNewMoney; + BigDecimal giftNewMoney; + BigDecimal cashNewAmount; + + synchronized (userId) { + MemberUserDO user = userService.getUser(userId); + + //新的总价 + String s = deductionRedisTemplate.opsForValue().get(dishOrderDO.getDiningPlatesNum() + "-" + dishOrderDO.getStoreId()); + BigDecimal total = new BigDecimal(StrUtil.isBlank(s) ? "0" : s); + //现有金额 + BigDecimal money = user.getMoney(); + //计算减免价格 + BigDecimal reductionAmount = BigDecimal.ZERO; + if (total.compareTo(BigDecimal.ZERO) > 0) { + reductionAmount = userService.getReductionAmount(userId, total, dishOrderDO.getCreateTime()); + } + if(dishOrderDO.getReductionAmount().compareTo(BigDecimal.ZERO) > 0){ + reductionAmount = reductionAmount.add(dishOrderDO.getReductionAmount()); + dishOrderDO.setReductionAmount(reductionAmount); + }else { + dishOrderDO.setReductionAmount(reductionAmount); + } + dishOrderDO.setReductionState(reductionAmount.compareTo(BigDecimal.ZERO) > 0 ? "1" : "0"); + //计算减免后的总价 + if (total.compareTo(reductionAmount) < 0) { + total = BigDecimal.ZERO; + } else { + total = total.subtract(reductionAmount); + } + + BigDecimal wxAmount = user.getWxAmount(); + BigDecimal giftAmount = user.getGiftAmount(); + BigDecimal cashAmount = user.getCashAmount(); + + user.setMoney(money.subtract(total)); + + //待支付金额 最大退款金额 + dishOrderDO.setRefundAmount(total); + if (money.compareTo(BigDecimal.ZERO) <= 0) { + dishOrderDO.setPayAmount(total); + dishOrderDO.setRefundAmount(BigDecimal.ZERO); + } else { + if (total.compareTo(money) > 0) { + dishOrderDO.setPayAmount(total.subtract(money)); + dishOrderDO.setRefundAmount(money); + } + } + + if (total.compareTo(money) > 0) { + dishOrderDO.setOrderStatus(DishOrderDO.TOCOMPLETE); + dishOrderDO.setWxAmount(wxAmount); + dishOrderDO.setCashAmount(cashAmount); + dishOrderDO.setGiftAmount(giftAmount); + + user.setWxAmount(BigDecimal.ZERO); + user.setCashAmount(BigDecimal.ZERO); + user.setGiftAmount(BigDecimal.ZERO); + } else { + dishOrderDO.setOrderStatus(DishOrderDO.COMPLETE); + //计算金额 + if (total.compareTo(cashAmount) <= 0) { + user.setCashAmount(cashAmount.subtract(total)); + dishOrderDO.setCashAmount(total); + } else { + user.setCashAmount(BigDecimal.ZERO); + dishOrderDO.setCashAmount(cashAmount); + BigDecimal total1 = total.subtract(cashAmount); + if (total1.compareTo(giftAmount) <= 0) { + user.setGiftAmount(giftAmount.subtract(total1)); + dishOrderDO.setGiftAmount(total1); + } else { + user.setGiftAmount(BigDecimal.ZERO); + dishOrderDO.setGiftAmount(giftAmount); + BigDecimal total2 = total1.subtract(giftAmount); + + user.setWxAmount(wxAmount.subtract(total2)); + dishOrderDO.setWxAmount(total2); + } + } + } + + userService.updateById(user); + newMoney = user.getMoney(); + wxNewMoney = user.getWxAmount(); + giftNewMoney = user.getGiftAmount(); + cashNewAmount = user.getCashAmount(); + changeMoney = total; + } + + + //记录消费记录 + CardDO cardDO = new CardDO(); + cardDO.setType(TimePeriodEnum.getTimePeriod(dishOrderDO.getCreateTime())); + cardDO.setUserId(userId); + cardDO.setChangeMoney(changeMoney); + cardDO.setFlag(CardDO.MINUS); + cardDO.setMoney(newMoney); + cardDO.setCashAmount(cashNewAmount); + cardDO.setWxAmount(wxNewMoney); + cardDO.setGiftAmount(giftNewMoney); + + cardService.insertOne(cardDO); + + dishOrderDO.setTotalMoney(changeMoney); + dishOrderDO.setUpdateTime(LocalDateTime.now()); + deductionRedisTemplate.delete(dishOrderDO.getDiningPlatesNum() + "-" + dishOrderDO.getStoreId()); + + //更新营业数据 + if(dishOrderDO.getOrderStatus().equals(DishOrderDO.COMPLETE)){ + StatisticsVo statisticsVo = new StatisticsVo(); + statisticsVo.setCarteenId(dishOrderDO.getStoreId()); + statisticsVo.setTotalMoney(dishOrderDO.getTotalMoney()); + statisticsVo.setOrder_sum(1); + statisticsVo.setReduceMoney(dishOrderDO.getReductionAmount()); + statisticsVo.setTime(dishOrderDO.getCreateTime()); + statisticsVo.setOrderId(dishOrderDO.getId()); + businessService.updateStatistics(statisticsVo); + } + return dishOrderDO; + } + + + @Override + public void cashDraw(Long userId, BigDecimal money) { + + BigDecimal newMoney; + BigDecimal wxNewMoney; + BigDecimal giftNewMoney; + BigDecimal cashNewAmount; + + synchronized (userId){ + MemberUserDO user = userService.getUser(userId); + if (ObjectUtil.isEmpty(user) || user.getCashAmount().compareTo(BigDecimal.ZERO) < 1 + || money.compareTo(user.getCashAmount()) > 0) { + throw exception(CASH_AMOUNT_NOT_ENOUGH); + } + user.setMoney(user.getMoney().subtract(money)); + user.setCashAmount(user.getCashAmount().subtract(money)); + userService.updateById(user); + newMoney = user.getMoney(); + wxNewMoney = user.getWxAmount(); + giftNewMoney = user.getGiftAmount(); + cashNewAmount = user.getCashAmount(); + } + + CardDO cardDO = new CardDO(); + cardDO.setUserId(userId); + cardDO.setFlag(CardDO.MINUS); + cardDO.setChangeMoney(money); + cardDO.setType(CostTypeEnum.CASH_WITHDRAW.getCode()); + cardDO.setWxAmount(wxNewMoney); + cardDO.setGiftAmount(giftNewMoney); + cardDO.setMoney(newMoney); + cardDO.setCashAmount(cashNewAmount); + cardService.insertOne(cardDO); + } + + + @Override + public void wxDraw(Integer amount, Long userId) { + BigDecimal newMoney; + BigDecimal wxNewMoney; + BigDecimal giftNewMoney; + BigDecimal cashNewAmount; + BigDecimal changeMoney = new BigDecimal(amount).divide(new BigDecimal("100")); + + synchronized (userId){ + MemberUserDO user = userService.getUser(userId); + user.setWxAmount(user.getWxAmount().subtract(changeMoney)); + user.setMoney(user.getMoney().subtract(changeMoney)); + userService.updateById(user); + newMoney = user.getMoney(); + wxNewMoney = user.getWxAmount(); + giftNewMoney = user.getGiftAmount(); + cashNewAmount = user.getCashAmount(); + } + + + //获取最新余额 + CardDO cardDO = new CardDO(); + cardDO.setUserId(userId); + cardDO.setFlag(CardDO.MINUS); + cardDO.setChangeMoney(changeMoney); + cardDO.setType("7"); + + cardDO.setWxAmount(wxNewMoney); + cardDO.setGiftAmount(giftNewMoney); + cardDO.setMoney(newMoney); + cardDO.setCashAmount(cashNewAmount); + cardService.insertOne(cardDO); + } +} + diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/WxRechargeService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/WxRechargeService.java new file mode 100644 index 00000000..ec6df3fa --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/WxRechargeService.java @@ -0,0 +1,11 @@ +package cn.iocoder.yudao.module.member.service.amount; + +import java.math.BigDecimal; + + + + +public interface WxRechargeService { + + void wxRecharge(BigDecimal money, BigDecimal wxAmount, BigDecimal giftAmount, Long userId); +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/WxRechargeServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/WxRechargeServiceImpl.java new file mode 100644 index 00000000..9176b20f --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/amount/WxRechargeServiceImpl.java @@ -0,0 +1,204 @@ +package cn.iocoder.yudao.module.member.service.amount; + + +import cn.hutool.core.collection.CollectionUtil; +import cn.iocoder.yudao.module.member.dal.dataobject.card.CardDO; +import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO; +import cn.iocoder.yudao.module.member.dal.dataobject.rechargelog.RechargeLogDO; +import cn.iocoder.yudao.module.member.dal.dataobject.refund.RefundDO; +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; +import cn.iocoder.yudao.module.member.dal.mysql.card.CardMapper; +import cn.iocoder.yudao.module.member.dal.mysql.order.DishOrderMapper; +import cn.iocoder.yudao.module.member.dal.mysql.rechargelog.RechargeLogMapper; +import cn.iocoder.yudao.module.member.dal.mysql.refund.IntegralRefundMapper; +import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; +import cn.iocoder.yudao.module.member.enums.CostTypeEnum; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + + + +/** + * 微信充值 Service 实现类 + * + * @author 开发账号 + */ +@Service +@Slf4j +public class WxRechargeServiceImpl implements WxRechargeService { + @Resource + private MemberUserMapper userMapper; + @Resource + private DishOrderMapper dishOrderMapper; + @Resource + private CardMapper cardMapper; + @Resource + private IntegralRefundMapper refundMapper; + @Resource + private RechargeLogMapper rechargeLogMapper; + + + @Override + public void wxRecharge(BigDecimal money, BigDecimal wxAmount, BigDecimal giftAmount, Long userId) { + + BigDecimal newMoney; + BigDecimal wxNewMoney; + BigDecimal giftNewMoney; + BigDecimal cashNewAmount; + + + synchronized (userId) { + //获取最新余额 + MemberUserDO memberUserDO = userMapper.selectById(userId); + + BigDecimal oldMoney = memberUserDO.getMoney(); + BigDecimal wxOldMoney = memberUserDO.getWxAmount(); + BigDecimal giftOldMoney = memberUserDO.getGiftAmount(); + BigDecimal cashAmount = memberUserDO.getCashAmount(); + + memberUserDO.setMoney(oldMoney.add(money)); + memberUserDO.setCashAmount(cashAmount); + memberUserDO.setGiftAmount(giftOldMoney); + memberUserDO.setWxAmount(wxOldMoney); + + if (memberUserDO.getMoney().compareTo(BigDecimal.ZERO) > 0) { + + if (oldMoney.compareTo(BigDecimal.ZERO) < 0) { + if (wxAmount.add(oldMoney).compareTo(BigDecimal.ZERO) >= 0) { + memberUserDO.setWxAmount(wxAmount.add(oldMoney)); + memberUserDO.setGiftAmount(giftOldMoney.add(giftAmount)); + } else { + BigDecimal left = wxAmount.add(oldMoney); + memberUserDO.setWxAmount(BigDecimal.ZERO); + memberUserDO.setGiftAmount(giftAmount.add(left)); + } + } else { + memberUserDO.setWxAmount(wxOldMoney.add(wxAmount)); + memberUserDO.setGiftAmount(giftOldMoney.add(giftAmount)); + + } + } + + userMapper.updateById(memberUserDO); + + newMoney = memberUserDO.getMoney(); + wxNewMoney = memberUserDO.getWxAmount(); + giftNewMoney = memberUserDO.getGiftAmount(); + cashNewAmount = memberUserDO.getCashAmount(); + + } + + + //明细处理 + CardDO cardDO = new CardDO(); + cardDO.setUserId(userId); + cardDO.setFlag(CardDO.ADD); + cardDO.setChangeMoney(money); + cardDO.setType(CostTypeEnum.WX_PAY.getCode()); + cardDO.setMoney(newMoney); + cardDO.setCashAmount(wxNewMoney); + cardDO.setGiftAmount(giftNewMoney); + cardDO.setWxAmount(cashNewAmount); + //处理未完全支付订单 + handleOrderWx(cardDO.getUserId(), money, wxAmount, giftAmount); + + cardMapper.insert(cardDO); + + + } + + void handleOrderWx(Long userId, BigDecimal money, BigDecimal wxMoney, BigDecimal giftMoney) { + + //开始的微信金额 + BigDecimal wxStart = wxMoney; + //已审核的订单 + List refundOrder = getRefundOrder(); + + //查询出所有未完全支付订单 + List dishOrderDOS = dishOrderMapper.selectList(Wrappers.lambdaQuery() + .eq(DishOrderDO::getUserId, userId).eq(DishOrderDO::getOrderStatus, DishOrderDO.TOCOMPLETE)); + + ArrayList updateList = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(dishOrderDOS)) { + for (DishOrderDO dishOrderDO : dishOrderDOS) { + BigDecimal payAmount = dishOrderDO.getPayAmount(); + if (payAmount.compareTo(money) <= 0) { + dishOrderDO.setOrderStatus(DishOrderDO.COMPLETE); + dishOrderDO.setPayAmount(BigDecimal.ZERO); + dishOrderDO.setRefundAmount(dishOrderDO.getRefundAmount().add(payAmount)); + if (refundOrder.contains(dishOrderDO.getId())) { + dishOrderDO.setRefundAmount(BigDecimal.ZERO); + } + if (payAmount.compareTo(wxMoney) <= 0) { + dishOrderDO.setWxAmount(dishOrderDO.getWxAmount().add(payAmount)); + wxMoney = wxMoney.subtract(payAmount); + } else { + dishOrderDO.setWxAmount(dishOrderDO.getWxAmount().add(wxMoney)); + wxMoney = BigDecimal.ZERO; + BigDecimal left = payAmount.subtract(wxMoney); + dishOrderDO.setGiftAmount(dishOrderDO.getGiftAmount().add(left)); + giftMoney = giftMoney.subtract(left); + } + money = money.subtract(payAmount); + + updateList.add(dishOrderDO); + } else { + dishOrderDO.setPayAmount(payAmount.subtract(money)); + dishOrderDO.setRefundAmount(dishOrderDO.getRefundAmount().add(money)); + if (refundOrder.contains(dishOrderDO.getId())) { + dishOrderDO.setRefundAmount(BigDecimal.ZERO); + } + dishOrderDO.setWxAmount(dishOrderDO.getWxAmount().add(wxMoney)); + dishOrderDO.setGiftAmount(dishOrderDO.getGiftAmount().add(giftMoney)); + wxMoney = BigDecimal.ZERO; + updateList.add(dishOrderDO); + break; + } + } + } + + rechargeLog(wxStart.subtract(wxMoney)); + if (CollectionUtil.isNotEmpty(updateList)) { + dishOrderMapper.updateBatch(updateList); + } + + } + + //补充金额记录 + public void rechargeLog(BigDecimal money) { + List rechargeLogDOList = rechargeLogMapper.selectList(Wrappers.lambdaQuery() + .apply("TO_DAYS(NOW())-TO_DAYS(create_time) = 0")); + if (CollectionUtil.isNotEmpty(rechargeLogDOList)) { + RechargeLogDO rechargeLogDO = rechargeLogDOList.get(0); + rechargeLogDO.setMoney(rechargeLogDO.getMoney().add(money)); + rechargeLogMapper.updateById(rechargeLogDO); + } else { + RechargeLogDO rechargeLogDO = new RechargeLogDO(); + rechargeLogDO.setMoney(money); + rechargeLogDO.setCreateTime(LocalDateTime.now()); + rechargeLogMapper.insert(rechargeLogDO); + } + } + + public List getRefundOrder() { + List refundDOS = refundMapper.selectList(Wrappers.lambdaQuery().in(RefundDO::getStatus, Arrays.asList("2", "3"))); + ArrayList orderIds = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(refundDOS)) { + List collect = refundDOS.stream().map(RefundDO::getOrderId).collect(Collectors.toList()); + orderIds.addAll(collect); + } + + return orderIds; + } + + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/business/BusinessService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/business/BusinessService.java index d051ed14..411f3f63 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/business/BusinessService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/business/BusinessService.java @@ -2,11 +2,14 @@ package cn.iocoder.yudao.module.member.service.business; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.controller.admin.business.vo.BusinessPageReqVO; +import cn.iocoder.yudao.module.member.controller.admin.business.vo.BusinessRespVO; import cn.iocoder.yudao.module.member.controller.admin.business.vo.BusinessSaveReqVO; import cn.iocoder.yudao.module.member.controller.admin.business.vo.StatisticsVo; +import cn.iocoder.yudao.module.member.controller.app.business.vo.BusinessDataVO; import cn.iocoder.yudao.module.member.dal.dataobject.business.BusinessDO; import javax.validation.*; +import java.util.List; /** * 营业统计 Service 接口 @@ -56,4 +59,9 @@ public interface BusinessService { void updateStatistics(StatisticsVo vo); + BusinessDataVO getDay(String time, Long carteenId); + + BusinessDataVO getWeek(String time,Long carteenId); + + BusinessDataVO getMonth(String time,Long carteenId); } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/business/BusinessServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/business/BusinessServiceImpl.java index 9ee271b3..6e7019b8 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/business/BusinessServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/business/BusinessServiceImpl.java @@ -1,11 +1,14 @@ package cn.iocoder.yudao.module.member.service.business; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.controller.admin.business.vo.BusinessPageReqVO; +import cn.iocoder.yudao.module.member.controller.admin.business.vo.BusinessRespVO; import cn.iocoder.yudao.module.member.controller.admin.business.vo.BusinessSaveReqVO; import cn.iocoder.yudao.module.member.controller.admin.business.vo.StatisticsVo; +import cn.iocoder.yudao.module.member.controller.app.business.vo.BusinessDataVO; import cn.iocoder.yudao.module.member.dal.dataobject.business.BusinessDO; import cn.iocoder.yudao.module.member.dal.dataobject.orderdetail.OrderDetailDO; import cn.iocoder.yudao.module.member.dal.mysql.business.BusinessMapper; @@ -15,7 +18,9 @@ import cn.iocoder.yudao.module.member.dal.mysql.orderdetail.OrderDetailMapper; import cn.iocoder.yudao.module.member.enums.CostTypeEnum; import cn.iocoder.yudao.module.member.enums.TimePeriodEnum; import cn.iocoder.yudao.module.member.service.orderdetail.OrderDetailService; +import cn.iocoder.yudao.module.member.util.MemberTimeUtils; import cn.iocoder.yudao.module.system.enums.ErrorCodeConstants; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import org.springframework.stereotype.Service; @@ -26,10 +31,15 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import java.math.BigDecimal; +import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; -import java.util.List; +import java.time.YearMonth; +import java.time.format.DateTimeFormatter; +import java.time.temporal.WeekFields; +import java.util.*; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -94,55 +104,267 @@ public class BusinessServiceImpl implements BusinessService { } @Override - public synchronized void updateStatistics(StatisticsVo vo) { - // 获取今天的开始时间 - LocalDateTime startOfDay = LocalDate.now().atStartOfDay(); - // 获取今天的结束时间 (23:59:59.999) - LocalDateTime endOfDay = LocalDateTime.of(LocalDate.now(), LocalTime.MAX); + public void updateStatistics(StatisticsVo vo) { + synchronized(vo.getCarteenId()){ + // 获取今天的开始时间 + LocalDateTime startOfDay = LocalDate.now().atStartOfDay(); + // 获取今天的结束时间 (23:59:59.999) + LocalDateTime endOfDay = LocalDateTime.of(LocalDate.now(), LocalTime.MAX); - List businessDOS = businessMapper.selectList(Wrappers.lambdaQuery() - .between(BusinessDO::getCreateTime, startOfDay, endOfDay) - .eq(BusinessDO::getCarteenId, vo.getCarteenId())); - if (CollectionUtil.isNotEmpty(businessDOS)) { - BusinessDO businessDO = businessDOS.get(0); + List businessDOS = businessMapper.selectList(Wrappers.lambdaQuery() + .between(BusinessDO::getCreateTime, startOfDay, endOfDay) + .eq(BusinessDO::getCarteenId, vo.getCarteenId())); + if (CollectionUtil.isNotEmpty(businessDOS)) { + BusinessDO businessDO = businessDOS.get(0); - //重量 - if(ObjectUtil.isNotEmpty(vo.getOrderId())){ - List orderDetailDOS = orderDetailMapper.selectList(Wrappers.lambdaQuery().eq(OrderDetailDO::getOrderId, vo.getOrderId())); - if (CollectionUtil.isNotEmpty(orderDetailDOS)) { - BigDecimal reduce = orderDetailDOS.stream().map(OrderDetailDO::getWeight).reduce(BigDecimal.ZERO, BigDecimal::add); - businessDO.setWeigh(businessDO.getWeigh().add(reduce)); + //重量 + if(ObjectUtil.isNotEmpty(vo.getOrderId())){ + List orderDetailDOS = orderDetailMapper.selectList(Wrappers.lambdaQuery().eq(OrderDetailDO::getOrderId, vo.getOrderId())); + if (CollectionUtil.isNotEmpty(orderDetailDOS)) { + BigDecimal reduce = orderDetailDOS.stream().map(OrderDetailDO::getWeight).reduce(BigDecimal.ZERO, BigDecimal::add); + businessDO.setWeigh(businessDO.getWeigh().add(reduce)); + } } - } - //订单数 - businessDO.setOrderSum(businessDO.getOrderSum() + vo.getOrder_sum()); + //订单数 + businessDO.setOrderSum(businessDO.getOrderSum() + vo.getOrder_sum()); - //营业额 - if(ObjectUtil.isNotEmpty(vo.getTotalMoney())){ - businessDO.setTurnover(businessDO.getTurnover().add(vo.getTotalMoney())); - } - //减免金额 - if(ObjectUtil.isNotEmpty(vo.getReduceMoney())){ - businessDO.setReduce(businessDO.getReduce().add(vo.getReduceMoney())); - } - - //早中晚金额 - if(ObjectUtil.isNotEmpty(vo.getTime())){ - String timePeriod = TimePeriodEnum.getTimePeriod(vo.getTime()); - - if(timePeriod.equals(CostTypeEnum.MORNING.getCode())){ - businessDO.setBreakfast(businessDO.getBreakfast().add(vo.getTotalMoney())); - }else if (timePeriod.equals(CostTypeEnum.NOON.getCode())){ - businessDO.setLunch(businessDO.getLunch().add(vo.getTotalMoney())); - }else if (timePeriod.equals(CostTypeEnum.NIGHT.getCode())){ - businessDO.setDinner(businessDO.getDinner().add(vo.getTotalMoney())); + //营业额 + if(ObjectUtil.isNotEmpty(vo.getTotalMoney())){ + businessDO.setTurnover(businessDO.getTurnover().add(vo.getTotalMoney())); } - } - businessMapper.updateById(businessDO); + //客单价 + if(businessDO.getOrderSum() != 0){ + businessDO.setPriceAvg(businessDO.getTurnover().divide(new BigDecimal(businessDO.getOrderSum()), 2, RoundingMode.HALF_UP)); + } + + //减免金额 + if(ObjectUtil.isNotEmpty(vo.getReduceMoney())){ + businessDO.setReduce(businessDO.getReduce().add(vo.getReduceMoney())); + } + + //早中晚金额 + if(ObjectUtil.isNotEmpty(vo.getTime())){ + String timePeriod = TimePeriodEnum.getTimePeriod(vo.getTime()); + + if(timePeriod.equals(CostTypeEnum.MORNING.getCode())){ + businessDO.setBreakfast(businessDO.getBreakfast().add(vo.getTotalMoney())); + }else if (timePeriod.equals(CostTypeEnum.NOON.getCode())){ + businessDO.setLunch(businessDO.getLunch().add(vo.getTotalMoney())); + }else if (timePeriod.equals(CostTypeEnum.NIGHT.getCode())){ + businessDO.setDinner(businessDO.getDinner().add(vo.getTotalMoney())); + } + } + + businessMapper.updateById(businessDO); + } } - } + + @Override + public BusinessDataVO getDay(String time,Long carteenId) { + + BusinessDataVO businessDataVO = new BusinessDataVO(); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(BusinessDO::getCarteenId,carteenId); + wrapper.orderByAsc(BusinessDO::getCreateTime); + wrapper.apply("DATE_FORMAT(create_time, '%Y-%m') = {0}", time); + List businessDOS = businessMapper.selectList(wrapper); + + Map map = businessDOS.stream().collect(Collectors.toMap( + vo -> vo.getCreateTime().toLocalDate().getDayOfMonth() + , vo -> vo, (existing, replacement) -> existing)); + + // 创建一个Map来存储每天的数据 + Map monthData = new LinkedHashMap<>(); + + + // 定义日期格式化器 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM"); + + // 将字符串解析为 YearMonth 对象 + YearMonth yearMonth = YearMonth.parse(time, formatter); + + // 获取当月的总天数 + int daysInMonth = yearMonth.lengthOfMonth(); + + //获取上一个月最后一天的数据 + // 获取上一个月的最后一天 + YearMonth previousMonth = yearMonth.minusMonths(1); + LocalDate lastDayOfPreviousMonth = previousMonth.atEndOfMonth(); + // 定义格式化器,将 LocalDate 转换为 yyyy-MM-dd 格式 + DateTimeFormatter formatterDay = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + // 将 LocalDate 转换为指定格式的字符串 + String formattedDate = lastDayOfPreviousMonth.format(formatterDay); + + + LambdaQueryWrapper previousWrapper = new LambdaQueryWrapper<>(); + previousWrapper.eq(BusinessDO::getCarteenId,carteenId); + previousWrapper.orderByAsc(BusinessDO::getCreateTime); + previousWrapper.apply("DATE_FORMAT(create_time, '%Y-%m-%d') = {0}", formattedDate); + List previousList = businessMapper.selectList(previousWrapper); + BusinessRespVO old = new BusinessRespVO(); + if(CollectionUtil.isNotEmpty(previousList)){ + BeanUtil.copyProperties(previousList.get(0), old); + }else { + old.setTurnover(BigDecimal.ZERO).setOrderSum(0).setReduce(BigDecimal.ZERO).setWeigh(BigDecimal.ZERO) + .setBreakfast(BigDecimal.ZERO).setLunch(BigDecimal.ZERO).setDinner(BigDecimal.ZERO); + } + + // 循环遍历该月的每一天 + for (int day = 1; day <= daysInMonth; day++) { + BusinessRespVO bean = new BusinessRespVO(); + if(map.get(day) == null){ + bean.setTurnover(BigDecimal.ZERO).setOrderSum(0).setReduce(BigDecimal.ZERO).setWeigh(BigDecimal.ZERO) + .setBreakfast(BigDecimal.ZERO).setLunch(BigDecimal.ZERO).setDinner(BigDecimal.ZERO) + .setTime(String.valueOf(day)); + }else { + bean = BeanUtils.toBean(map.get(day), BusinessRespVO.class); + bean.setTime(String.valueOf(day)); + } + //计算差额 + if(day == 1){ + compare(bean,old); + }else { + compare(bean,monthData.get(day-1)); + } + monthData.put(day,bean); + + } + + businessDataVO.setBusinessList(new ArrayList<>(monthData.values())); + return businessDataVO; + } + + @Override + public BusinessDataVO getWeek(String time,Long carteenId) { + + BusinessDataVO businessDataVO = new BusinessDataVO(); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(BusinessDO::getCarteenId,carteenId); + wrapper.orderByAsc(BusinessDO::getCreateTime); + wrapper.apply("DATE_FORMAT(create_time, '%Y-%m') = {0}", time); + List businessDOS = businessMapper.selectList(wrapper); + + Map map = new HashMap<>(); + + int totalWeeksOfMonth = MemberTimeUtils.getTotalWeeksOfMonth(time); + for (int i = 1; i <= totalWeeksOfMonth; i++) { + BusinessRespVO bean = new BusinessRespVO(); + bean.setTurnover(BigDecimal.ZERO).setOrderSum(0).setReduce(BigDecimal.ZERO).setWeigh(BigDecimal.ZERO) + .setBreakfast(BigDecimal.ZERO).setLunch(BigDecimal.ZERO).setDinner(BigDecimal.ZERO) + .setTime(String.valueOf(i)); + map.put(i,bean); + } + + for (BusinessDO businessDO : businessDOS) { + + LocalDate date = businessDO.getCreateTime().toLocalDate(); + + // 获取区域的周定义(可以是ISO标准或其他区域标准) + WeekFields weekFields = WeekFields.of(Locale.getDefault()); + + // 使用weekFields获取当前日期属于当月的第几周 + int i = date.get(weekFields.weekOfMonth()); + BusinessRespVO businessRespVO = map.get(i); + handleBusiness(businessDO,businessRespVO); + } + + + businessDataVO.setBusinessList(new ArrayList<>(map.values())); + return businessDataVO; + } + + @Override + public BusinessDataVO getMonth(String time,Long carteenId) { + + BusinessDataVO businessDataVO = new BusinessDataVO(); + + int year = MemberTimeUtils.getYearFromYearMonthString(time); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(BusinessDO::getCarteenId,carteenId); + wrapper.orderByAsc(BusinessDO::getCreateTime); + wrapper.apply("DATE_FORMAT(create_time, '%Y') = {0}", year); + List businessDOS = businessMapper.selectList(wrapper); + + Map map = new HashMap<>(); + //时间处理 + for (int i = 1; i <= 12; i++) { + BusinessRespVO bean = new BusinessRespVO(); + bean.setTurnover(BigDecimal.ZERO).setOrderSum(0).setReduce(BigDecimal.ZERO).setWeigh(BigDecimal.ZERO) + .setBreakfast(BigDecimal.ZERO).setLunch(BigDecimal.ZERO).setDinner(BigDecimal.ZERO) + .setTime(String.valueOf(i)); + map.put(i,bean); + } + //数据统计 + for (BusinessDO businessDO : businessDOS) { + + LocalDate date = businessDO.getCreateTime().toLocalDate(); + + // 当前日期属于哪月 + int i = date.getMonthValue(); + BusinessRespVO businessRespVO = map.get(i); + handleBusiness(businessDO,businessRespVO); + } + + //上一年最后一月 + int previousYear = year - 1; + LambdaQueryWrapper previousWrapper = new LambdaQueryWrapper<>(); + previousWrapper.eq(BusinessDO::getCarteenId,carteenId); + previousWrapper.orderByAsc(BusinessDO::getCreateTime); + previousWrapper.apply("DATE_FORMAT(create_time, '%Y-%m') = {0}", previousYear+"-12"); + List previousList = businessMapper.selectList(previousWrapper); + BusinessRespVO previousVO = new BusinessRespVO(); + previousVO.setTurnover(BigDecimal.ZERO).setOrderSum(0).setReduce(BigDecimal.ZERO).setWeigh(BigDecimal.ZERO) + .setBreakfast(BigDecimal.ZERO).setLunch(BigDecimal.ZERO).setDinner(BigDecimal.ZERO); + for (BusinessDO businessDO : previousList) { + handleBusiness(businessDO,previousVO); + } + //差额统计 + for (int i = 1; i <= 12; i++) { + if(i == 1){ + compare(map.get(i),previousVO); + }else { + compare(map.get(i),map.get(i-1)); + } + } + + businessDataVO.setBusinessList(new ArrayList<>(map.values())); + + return businessDataVO; + } + + + void handleBusiness(BusinessDO businessDO, BusinessRespVO businessRespVO) { + //营业额 + businessRespVO.setTurnover(businessRespVO.getTurnover().add(businessDO.getTurnover())); + //订单数 + businessRespVO.setOrderSum(businessRespVO.getOrderSum()+businessDO.getOrderSum()); + //均单价 + businessRespVO.setPriceAvg(businessDO.getTurnover().divide(new BigDecimal(businessDO.getOrderSum()), 2, RoundingMode.HALF_UP)); + //减免金额 + businessRespVO.setReduce(businessRespVO.getReduce().add(businessDO.getReduce())); + //重量 + businessRespVO.setWeigh(businessRespVO.getWeigh().add(businessDO.getWeigh())); + //早 + businessRespVO.setBreakfast(businessRespVO.getBreakfast().add(businessDO.getBreakfast())); + //中 + businessRespVO.setLunch(businessRespVO.getLunch().add(businessDO.getLunch())); + //晚 + businessRespVO.setDinner(businessRespVO.getDinner().add(businessDO.getDinner())); + //门店 + businessRespVO.setCarteenId(businessDO.getCarteenId()); + } + + void compare(BusinessRespVO today, BusinessRespVO last) { + today.setTurnoverCompare(today.getTurnover().subtract(last.getTurnover())); + today.setOrderSumCompare(today.getOrderSum()-last.getOrderSum()); + today.setPriceAvgCompare(today.getPriceAvg().subtract(last.getPriceAvg())); + } + } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/storeorder/StoreOrderService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/storeorder/StoreOrderService.java index 3b07db00..92d582c6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/storeorder/StoreOrderService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/storeorder/StoreOrderService.java @@ -62,5 +62,7 @@ public interface StoreOrderService { String cardPay(StoreOrderDto dto); + String codePay(StoreOrderDto dto); + void batchCacheOrder(StoreOrderUploadDto dto); } \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/storeorder/StoreOrderServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/storeorder/StoreOrderServiceImpl.java index a74c2d0f..2c769b0d 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/storeorder/StoreOrderServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/storeorder/StoreOrderServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.service.storeorder; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.member.controller.admin.storeorder.vo.StoreOrderPageReqVO; @@ -35,6 +36,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.STORE_ORDER_NOT_EXISTS; +import static cn.iocoder.yudao.module.member.util.QRCodeWithJWTUtil.validateJWT; /** * 商品订单 Service 实现类 @@ -154,6 +156,23 @@ public class StoreOrderServiceImpl implements StoreOrderService { } } + @Override + public String codePay(StoreOrderDto dto) { + String s = validateJWT(dto.getJwt()); + if (StrUtil.isBlank(s)) { + return "二维码过期"; + } + MemberUserDO user = userService.getUser(Long.valueOf(s)); + Double totalPrice = createOrder(dto).getTotalPrice(); + BigDecimal total = BigDecimal.valueOf(totalPrice).setScale(2, RoundingMode.HALF_UP); + + BigDecimal compute = compute(total, user.getId()); + if (compute.compareTo(BigDecimal.ZERO) < 0) { + return "金额不足"; + } + return null; + } + @Override public void batchCacheOrder(StoreOrderUploadDto dto) { for (StoreLocalOrderDto orderDto :dto.getMgcrCacheOrderVoList()){ diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java index edc5f39d..3e2e0302 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java @@ -86,6 +86,8 @@ public interface MemberUserService { */ MemberUserDO getUser(Long id); + void updateById(MemberUserDO memberUserDO); + /** * 通过用户 ID 查询用户们 * @@ -257,4 +259,5 @@ public interface MemberUserService { boolean delete(Long userId); + String getQRCode(); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java index dfa3c47b..9a81c04a 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java @@ -51,6 +51,7 @@ import cn.iocoder.yudao.module.member.service.orderdetail.OrderDetailService; import cn.iocoder.yudao.module.member.service.tag.MemberTagService; import cn.iocoder.yudao.module.member.service.userexpand.UserExpandService; import cn.iocoder.yudao.module.member.util.MemberConstants; +import cn.iocoder.yudao.module.member.util.QRCodeWithJWTUtil; import cn.iocoder.yudao.module.system.api.dishesnutrition.DishesNutritionApi; import cn.iocoder.yudao.module.system.api.dishesnutrition.dto.DishesNutritionRespDTO; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; @@ -63,6 +64,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -83,12 +85,16 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.setLoginUser; import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.member.util.QRCodeWithJWTUtil.generateJWT; +import static cn.iocoder.yudao.module.member.util.QRCodeWithJWTUtil.validateJWT; /** * 会员 User Service 实现类 @@ -140,6 +146,9 @@ public class MemberUserServiceImpl implements MemberUserService { @Resource private MemberTagService memberTagService; + @Resource + private StringRedisTemplate memberUserRedisTemplate; + @Override public MemberUserDO getUserByMobile(String mobile) { @@ -209,6 +218,11 @@ public class MemberUserServiceImpl implements MemberUserService { return memberUserMapper.selectById(id); } + @Override + public void updateById(MemberUserDO memberUserDO) { + memberUserMapper.updateById(memberUserDO); + } + @Override public List getUserList(Collection ids) { if (CollUtil.isEmpty(ids)) { @@ -892,4 +906,21 @@ public class MemberUserServiceImpl implements MemberUserService { memberUserMapper.deleteFace(userId); return i>0; } + + @Override + public String getQRCode() { + Long userId = getLoginUserId(); + String redisKey = QRCodeWithJWTUtil.QR_PREFIX+userId; + String url = memberUserRedisTemplate.opsForValue().get(redisKey); + if(StrUtil.isNotEmpty(url)){ + return url; + } + + String jwt = generateJWT(userId); // 1分钟后过期 + String fileName = "QRCode_" + userId + ".png"; + String path = QRCodeWithJWTUtil.BASE_PATH+fileName; + QRCodeWithJWTUtil.generateQRCode(jwt, 350, 350, path); // 生 + memberUserRedisTemplate.opsForValue().set(redisKey,path,60, TimeUnit.SECONDS); + return path; + } } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/util/MemberTimeUtils.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/util/MemberTimeUtils.java new file mode 100644 index 00000000..484d771b --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/util/MemberTimeUtils.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.member.util; + +import java.time.LocalDate; +import java.time.YearMonth; +import java.time.temporal.WeekFields; +import java.util.Locale; + +public class MemberTimeUtils { + + // 获取指定月份总共有几周 + public static int getTotalWeeksOfMonth(String yearMonthString) { + // 获取该月的第一天和最后一天 + LocalDate firstDayOfMonth = convertToLocalDate(yearMonthString, true); + LocalDate lastDayOfMonth = firstDayOfMonth.withDayOfMonth(firstDayOfMonth.lengthOfMonth()); + + // 获取区域的周定义(可以是ISO标准或其他区域标准) + WeekFields weekFields = WeekFields.of(Locale.getDefault()); + + // 获取第一天和最后一天的周数 + int firstWeek = firstDayOfMonth.get(weekFields.weekOfMonth()); + int lastWeek = lastDayOfMonth.get(weekFields.weekOfMonth()); + + // 计算总周数 + return lastWeek - firstWeek + 1; + } + + // 将"yyyy-MM"字符串转换为LocalDate,并决定是该月的第一天还是最后一天 + public static LocalDate convertToLocalDate(String yearMonthString, boolean isFirstDay) { + // 使用YearMonth类处理"yyyy-MM"格式 + YearMonth yearMonth = YearMonth.parse(yearMonthString); + + // 如果isFirstDay为true,则返回该月的第一天,否则返回最后一天 + return isFirstDay ? yearMonth.atDay(1) : yearMonth.atEndOfMonth(); + } + + // 从"yyyy-MM"字符串中提取年份 + public static int getYearFromYearMonthString(String yearMonthString) { + // 使用YearMonth类解析字符串 + YearMonth yearMonth = YearMonth.parse(yearMonthString); + + // 返回年份 + return yearMonth.getYear(); + } +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/util/QRCodeWithJWTUtil.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/util/QRCodeWithJWTUtil.java new file mode 100644 index 00000000..202d0058 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/util/QRCodeWithJWTUtil.java @@ -0,0 +1,66 @@ +package cn.iocoder.yudao.module.member.util; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.extra.qrcode.QrCodeUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; + +import cn.hutool.jwt.JWTUtil; + + +import java.io.File; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + + +public class QRCodeWithJWTUtil { + private static final String SECRET_KEY = "your_secret_key"; // 使用HS256算法生成秘钥 + public static final String BASE_PATH = "qrCodes/"; + public static final String QR_PREFIX = "QRCODE_"; +// public static void main(String[] args) throws WriterException, IOException { +// // 用户ID +// Long userId = 123L; +// +// // 生成包含JWT的二维码 +// String jwt = generateJWT(userId, 1); // 1分钟后过期 +// String fileName = "QRCode_" + userId + ".png"; +// generateQRCode(jwt, 350, 350, BASE_PATH+fileName); // 生成二维码并保存 +// } + + // 生成 JWT + public static String generateJWT(Long userId) { + // 创建 JWT payload + Map payload = new HashMap<>(); + payload.put("userId", userId); + + // 设置过期时间为1分钟 + long expireTime = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(1); + payload.put("exp", expireTime); // 添加过期时间到 payload + + // 生成 JWT + + return JWTUtil.createToken(payload, SECRET_KEY.getBytes()); + } + + // 生成二维码图片 + public static void generateQRCode(String data, int width, int height, String filePath) { + QrCodeUtil.generate(data, width, height, new File(filePath)); + } + + // 验证JWT是否有效和未过期 + public static String validateJWT(String jwt) { + boolean isValid = JWTUtil.verify(jwt, SECRET_KEY.getBytes()); + if (isValid) { + System.out.println("JWT 验证成功!"); + // 解析 JWT + JSONObject payloads = JWTUtil.parseToken(jwt).getPayloads(); + Map map = JSONUtil.toBean(payloads, Map.class); + return map.get("userId").toString(); + } else { + System.out.println("JWT 验证失败!"); + } + return null; + } +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index 1a1f7eaa..94275721 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -174,6 +174,7 @@ public interface ErrorCodeConstants { ErrorCode CARTEEN_NOT_EXISt = new ErrorCode(1_002_029_002, "当前门店不存在"); // ========== 菜品管理 1-002-030-000 ========== ErrorCode DISHES_NOT_EXISTS = new ErrorCode(1_002_030_002, "当前菜品不存在"); + ErrorCode DISHES_EXISTS = new ErrorCode(1_002_030_003, "菜品名重复"); // ========== 菜品关联门店 1-002-032-000 ========== ErrorCode DISHES_TYPE_NOT_EXISTS = new ErrorCode(1_002_032_002, "当前菜品类型不存在"); // ========== 门店 流水 1_002_033_002 ========== diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dishimage/vo/DishImagePageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dishimage/vo/DishImagePageReqVO.java index d7009696..ee8c02f8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dishimage/vo/DishImagePageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dishimage/vo/DishImagePageReqVO.java @@ -19,12 +19,10 @@ public class DishImagePageReqVO extends PageParam { private String name; @Schema(description = "开始日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private String[] startDate; + private String startDate; @Schema(description = "结束日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private String[] endDate; + private String endDate; @Schema(description = "地址", example = "https://www.iocoder.cn") private String imageUrl; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dishes/vo/AppSaveVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dishes/vo/AppSaveVO.java index 0345faa3..b21ed59a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dishes/vo/AppSaveVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/dishes/vo/AppSaveVO.java @@ -22,4 +22,13 @@ public class AppSaveVO { @Schema(description = "总价格", example = "1") private BigDecimal dishesSumPrice; + + @Schema(description = "菜品图片", example = "1") + private String dishesImageUrl; + + @Schema(description = "周几", example = "星期一") + private String weekTime; + + @Schema(description = "时段", example = "早") + private String timeSlot; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dishes/DishesMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dishes/DishesMapper.java index f9547092..f660f915 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dishes/DishesMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dishes/DishesMapper.java @@ -30,6 +30,8 @@ public interface DishesMapper extends BaseMapperX { .eqIfPresent(DishesDO::getDishesVipWeighPrice, reqVO.getDishesVipWeighPrice()) .eqIfPresent(DishesDO::getDishecCook, reqVO.getDishecCook()) .eqIfPresent(DishesDO::getDishecType, reqVO.getDishecType()) + .eqIfPresent(DishesDO::getWeekTime, reqVO.getWeekTime()) + .eqIfPresent(DishesDO::getTimeSlot,reqVO.getTimeSlot()) .inIfPresent(DishesDO::getWeekTime, reqVO.getWeekTimes()) .betweenIfPresent(DishesDO::getCreateTime, reqVO.getCreateTime()) .orderByDesc(DishesDO::getId)); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dishimage/DishImageMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dishimage/DishImageMapper.java index c6c179f8..d1947fe8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dishimage/DishImageMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dishimage/DishImageMapper.java @@ -23,8 +23,8 @@ public interface DishImageMapper extends BaseMapperX { return selectPage(reqVO, new LambdaQueryWrapperX() .eqIfPresent(DishImageDO::getCarteenId,reqVO.getCarteenId()) .likeIfPresent(DishImageDO::getName, reqVO.getName()) - .betweenIfPresent(DishImageDO::getStartDate, reqVO.getStartDate()) - .betweenIfPresent(DishImageDO::getEndDate, reqVO.getEndDate()) + .eqIfPresent(DishImageDO::getStartDate, reqVO.getStartDate()) + .eqIfPresent(DishImageDO::getEndDate, reqVO.getEndDate()) .eqIfPresent(DishImageDO::getImageUrl, reqVO.getImageUrl()) .eqIfPresent(DishImageDO::getRemark, reqVO.getRemark()) .betweenIfPresent(DishImageDO::getCreateTime, reqVO.getCreateTime()) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dishes/DishesServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dishes/DishesServiceImpl.java index 13427578..cdf407df 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dishes/DishesServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dishes/DishesServiceImpl.java @@ -69,6 +69,8 @@ public class DishesServiceImpl implements DishesService { DishesDO dishes = BeanUtils.toBean(createReqVO, DishesDO.class); dishes.setDeleted(Boolean.FALSE); + checkDishes(dishes.getDishesName(),dishes.getCarteenId(),null); + LocalDateTime today = LocalDateTime.now(); int hour = today.getHour(); String time = dishesMapper.getTime(hour); @@ -115,6 +117,8 @@ public class DishesServiceImpl implements DishesService { dishes.setCarteenId(carteenId); dishes.setDishesNumber(new BigDecimal("50")); + checkDishes(dishes.getDishesName(),dishes.getCarteenId(),null); + LocalDateTime today = LocalDateTime.now(); int hour = today.getHour(); String time = dishesMapper.getTime(hour); @@ -144,6 +148,8 @@ public class DishesServiceImpl implements DishesService { // 更新 DishesDO updateObj = BeanUtils.toBean(updateReqVO, DishesDO.class); + checkDishes(updateObj.getDishesName(),updateObj.getCarteenId(),updateReqVO.getId()); + //计算每g多少钱 BigDecimal dishesSumPrice = updateObj.getDishesSumPrice(); BigDecimal dishesNumber = updateObj.getDishesNumber(); @@ -169,8 +175,11 @@ public class DishesServiceImpl implements DishesService { @Override public void updateDishesApp(AppUpdateVO vo) { + DishesDO dishesDO = validateDishesExists(vo.getId()); DishesDO updateObj = BeanUtils.toBean(vo, DishesDO.class); + checkDishes(updateObj.getDishesName(),dishesDO.getCarteenId(),vo.getId()); + //计算每g多少钱 BigDecimal dishesSumPrice = updateObj.getDishesSumPrice(); BigDecimal dishesNumber = new BigDecimal("50"); @@ -192,10 +201,12 @@ public class DishesServiceImpl implements DishesService { dishesMapper.deleteById(id); } - private void validateDishesExists(Long id) { - if (dishesMapper.selectById(id) == null) { + private DishesDO validateDishesExists(Long id) { + DishesDO dishesDO = dishesMapper.selectById(id); + if ( dishesDO == null) { throw exception(ErrorCodeConstants.DISHES_NOT_EXISTS); } + return dishesDO; } /** @@ -292,12 +303,21 @@ public class DishesServiceImpl implements DishesService { week.add(dayOfWeekInChinese); week.add("整周"); -// Long carteenId = deviceInfoService.getCarteen(getHearder()); List dishesDOS = dishesMapper.selectList(Wrappers.lambdaQuery() -// .eq(DishesDO::getCarteenId, carteenId) .in(DishesDO::getWeekTime, week) .orderByDesc(DishesDO::getCreateTime)); return dishesDOS; } + + void checkDishes(String dishName,Long carteenId,Long id){ + List dishesDOS = dishesMapper.selectList(Wrappers.lambdaQuery() + .eq(DishesDO::getCarteenId, carteenId) + .eq(DishesDO::getDishesName, dishName) + .ne(id!=null, DishesDO::getId, id)); + if(!dishesDOS.isEmpty()){ + throw exception(ErrorCodeConstants.DISHES_EXISTS); + } + } + } \ No newline at end of file