From 84971187ca91e21e542337e4fb542317c8c878d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=9D=BE?= <8605635+zhang3064194730@user.noreply.gitee.com> Date: Tue, 10 Dec 2024 11:07:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8E=92=E9=98=9F=E5=8F=AB=E5=8F=B7?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 +- .../controller/TbCallTableController.java | 111 ++++ .../cashierservice/entity/TbCallConfig.java | 46 +- .../cashierservice/entity/TbCallQueue.java | 26 +- .../dto/calltable/BaseCallTableDTO.java | 13 + .../entity/dto/calltable/CallQueueDTO.java | 13 + .../entity/dto/calltable/CallTableDTO.java | 29 + .../entity/dto/calltable/TakeNumberDTO.java | 18 + .../dto/calltable/UpdateCallQueueDTO.java | 15 + .../dto/calltable/UpdateCallTableDTO.java | 23 + .../entity/dto/calltable/UpdateConfigDTO.java | 16 + .../entity/vo/CallRecordVO.java | 12 + .../mapper/TbCallConfigMapper.java | 4 +- .../mapper/TbCallQueueMapper.java | 11 +- .../mapper/TbCallTableMapper.java | 4 +- .../service/TbCallConfigService.java | 13 + .../service/TbCallQueueService.java | 13 + .../cashierservice/service/TbCallService.java | 30 + .../service/TbCallTableService.java | 13 + .../service/impl/TbCallConfigServiceImpl.java | 22 + .../service/impl/TbCallQueueServiceImpl.java | 22 + .../service/impl/TbCallServiceImpl.java | 575 ++++++++++++++++++ .../service/impl/TbCallTableServiceImpl.java | 22 + .../cashierservice/util/RabbitMsgUtils.java | 17 + .../system/cashierservice/util/RedisCst.java | 7 +- .../system/cashierservice/util/TokenUtil.java | 10 + .../cashierservice/util/WxAccountUtil.java | 78 +++ src/main/resources/application.yml | 7 + .../resources/mapper/TbCallConfigMapper.xml | 5 +- .../resources/mapper/TbCallQueueMapper.xml | 3 +- .../resources/mapper/TbCallTableMapper.xml | 5 +- 31 files changed, 1141 insertions(+), 49 deletions(-) create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/controller/TbCallTableController.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/BaseCallTableDTO.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/CallQueueDTO.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/CallTableDTO.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/TakeNumberDTO.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateCallQueueDTO.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateCallTableDTO.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateConfigDTO.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/entity/vo/CallRecordVO.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallConfigService.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallQueueService.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallService.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallTableService.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallConfigServiceImpl.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallQueueServiceImpl.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallServiceImpl.java create mode 100644 src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallTableServiceImpl.java diff --git a/pom.xml b/pom.xml index 41b1491..3b4fccb 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,12 @@ - + + + com.google.zxing + core + 3.5.3 + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/controller/TbCallTableController.java b/src/main/java/com/chaozhanggui/system/cashierservice/controller/TbCallTableController.java new file mode 100644 index 0000000..9e6d75a --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/controller/TbCallTableController.java @@ -0,0 +1,111 @@ +package com.chaozhanggui.system.cashierservice.controller; + +import com.chaozhanggui.system.cashierservice.entity.dto.calltable.*; +import com.chaozhanggui.system.cashierservice.exception.MsgException; +import com.chaozhanggui.system.cashierservice.service.TbCallService; +import com.chaozhanggui.system.cashierservice.sign.CodeEnum; +import com.chaozhanggui.system.cashierservice.sign.Result; +import lombok.AllArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; + +/** + * 叫号 + */ +@RestController +@RequestMapping("/callTable") +@AllArgsConstructor +public class TbCallTableController { + + private static final Logger log = LoggerFactory.getLogger(TbCallTableController.class); + private final TbCallService tbCallService; + + @GetMapping + public Result get(@RequestParam(required = false) Integer callTableId, @RequestParam Integer shopId, + @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size, + @RequestParam(required = false) Integer state) { + return Result.success(CodeEnum.SUCCESS, tbCallService.get(page, size, shopId, callTableId, state)); + } + + @PostMapping + public Result add(@Validated @RequestBody CallTableDTO addCallTableDTO) { + return Result.success(CodeEnum.SUCCESS, tbCallService.add(addCallTableDTO)); + } + + + @PutMapping + public Result update(@Validated @RequestBody UpdateCallTableDTO callTableDTO) { + return Result.success(CodeEnum.SUCCESS, tbCallService.update(callTableDTO)); + } + + + @DeleteMapping + public Result delete(@Validated @RequestBody BaseCallTableDTO baseCallTableDTO) { + return Result.success(CodeEnum.SUCCESS, tbCallService.delete(baseCallTableDTO)); + } + + + @PostMapping("takeNumber") + public Result takeNumber(@Validated @RequestBody TakeNumberDTO takeNumberDTO) { + return Result.success(CodeEnum.SUCCESS, tbCallService.takeNumber(takeNumberDTO)); + } + + + @GetMapping("takeNumberCode") + public Result takeNumberCode(@RequestParam Integer shopId, @RequestParam Integer callTableId) { + return Result.success(CodeEnum.SUCCESS, tbCallService.takeNumberCode(shopId, callTableId)); + } + + + @PostMapping("call") + public Result call(@Validated @RequestBody CallQueueDTO callQueueDTO) { + try { + return Result.success(CodeEnum.SUCCESS, tbCallService.call(callQueueDTO)); + } catch (MsgException e) { + log.error("异常", e); + return Result.success(CodeEnum.SUCCESS, new HashMap() {{ + put("state", "0"); + put("message", e.getMessage()); + }}); + } + } + + + @PutMapping("updateState") + public Result confirm(@Validated @RequestBody UpdateCallQueueDTO updateCallQueueDTO) { + return Result.success(CodeEnum.SUCCESS, tbCallService.updateInfo(updateCallQueueDTO)); + } + + + @GetMapping("queue") + public Result getQueue(@RequestParam Integer shopId, @RequestParam(required = false) Integer callTableId, + @RequestParam(required = false) Integer state, @RequestParam(defaultValue = "1") Integer page, + @RequestParam(defaultValue = "10") Integer size) { + return Result.success(CodeEnum.SUCCESS, tbCallService.getQueue(shopId, callTableId, state, page, size)); + } + + + @GetMapping("callRecord") + public Result getCallRecord(@RequestParam Integer shopId, @RequestParam(required = false) Integer callTableId, + @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size) { + return Result.success(CodeEnum.SUCCESS, tbCallService.getCallRecord(shopId, callTableId, page, size)); + } + + + @GetMapping("config") + public Result getConfig(@RequestParam Integer shopId) { + return Result.success(CodeEnum.SUCCESS, tbCallService.getConfig(shopId)); + } + + + @PutMapping("config") + public Result updateConfig(@RequestBody UpdateConfigDTO configDTO) { + return Result.success(CodeEnum.SUCCESS, tbCallService.updateConfig(configDTO)); + } + +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbCallConfig.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbCallConfig.java index 6b4e3b3..268fecf 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbCallConfig.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbCallConfig.java @@ -8,7 +8,7 @@ import java.io.Serializable; import java.util.Date; /** - * + * 叫号配置表 * @TableName tb_call_config */ @TableName(value ="tb_call_config") @@ -65,14 +65,9 @@ public class TbCallConfig implements Serializable { private Date updateTime; /** - * 是否过号顺延 + * 临近几桌提醒 */ - private Integer isPostpone; - - /** - * 顺延号码数量 - */ - private Integer postponeNum; + private Integer nearNum; @TableField(exist = false) private static final long serialVersionUID = 1L; @@ -218,31 +213,17 @@ public class TbCallConfig implements Serializable { } /** - * 是否过号顺延 + * 临近几桌提醒 */ - public Integer getIsPostpone() { - return isPostpone; + public Integer getNearNum() { + return nearNum; } /** - * 是否过号顺延 + * 临近几桌提醒 */ - public void setIsPostpone(Integer isPostpone) { - this.isPostpone = isPostpone; - } - - /** - * 顺延号码数量 - */ - public Integer getPostponeNum() { - return postponeNum; - } - - /** - * 顺延号码数量 - */ - public void setPostponeNum(Integer postponeNum) { - this.postponeNum = postponeNum; + public void setNearNum(Integer nearNum) { + this.nearNum = nearNum; } @Override @@ -267,8 +248,7 @@ public class TbCallConfig implements Serializable { && (this.getShopId() == null ? other.getShopId() == null : this.getShopId().equals(other.getShopId())) && (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime())) && (this.getUpdateTime() == null ? other.getUpdateTime() == null : this.getUpdateTime().equals(other.getUpdateTime())) - && (this.getIsPostpone() == null ? other.getIsPostpone() == null : this.getIsPostpone().equals(other.getIsPostpone())) - && (this.getPostponeNum() == null ? other.getPostponeNum() == null : this.getPostponeNum().equals(other.getPostponeNum())); + && (this.getNearNum() == null ? other.getNearNum() == null : this.getNearNum().equals(other.getNearNum())); } @Override @@ -285,8 +265,7 @@ public class TbCallConfig implements Serializable { result = prime * result + ((getShopId() == null) ? 0 : getShopId().hashCode()); result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode()); result = prime * result + ((getUpdateTime() == null) ? 0 : getUpdateTime().hashCode()); - result = prime * result + ((getIsPostpone() == null) ? 0 : getIsPostpone().hashCode()); - result = prime * result + ((getPostponeNum() == null) ? 0 : getPostponeNum().hashCode()); + result = prime * result + ((getNearNum() == null) ? 0 : getNearNum().hashCode()); return result; } @@ -306,8 +285,7 @@ public class TbCallConfig implements Serializable { sb.append(", shopId=").append(shopId); sb.append(", createTime=").append(createTime); sb.append(", updateTime=").append(updateTime); - sb.append(", isPostpone=").append(isPostpone); - sb.append(", postponeNum=").append(postponeNum); + sb.append(", nearNum=").append(nearNum); sb.append(", serialVersionUID=").append(serialVersionUID); sb.append("]"); return sb.toString(); diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbCallQueue.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbCallQueue.java index f24b4d2..97af41f 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbCallQueue.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/TbCallQueue.java @@ -8,7 +8,7 @@ import java.io.Serializable; import java.util.Date; /** - * + * 叫号排号表 * @TableName tb_call_queue */ @TableName(value ="tb_call_queue") @@ -109,6 +109,11 @@ public class TbCallQueue implements Serializable { */ private String createDay; + /** + * 是否已经顺延 0 未顺延 1已顺延一次 2顺延一次仍然过号 + */ + private Integer isPostpone; + @TableField(exist = false) private static final long serialVersionUID = 1L; @@ -378,6 +383,20 @@ public class TbCallQueue implements Serializable { this.createDay = createDay; } + /** + * 是否已经顺延 0 未顺延 1已顺延一次 2顺延一次仍然过号 + */ + public Integer getIsPostpone() { + return isPostpone; + } + + /** + * 是否已经顺延 0 未顺延 1已顺延一次 2顺延一次仍然过号 + */ + public void setIsPostpone(Integer isPostpone) { + this.isPostpone = isPostpone; + } + @Override public boolean equals(Object that) { if (this == that) { @@ -408,7 +427,8 @@ public class TbCallQueue implements Serializable { && (this.getSubState() == null ? other.getSubState() == null : this.getSubState().equals(other.getSubState())) && (this.getConfirmTime() == null ? other.getConfirmTime() == null : this.getConfirmTime().equals(other.getConfirmTime())) && (this.getCallNum() == null ? other.getCallNum() == null : this.getCallNum().equals(other.getCallNum())) - && (this.getCreateDay() == null ? other.getCreateDay() == null : this.getCreateDay().equals(other.getCreateDay())); + && (this.getCreateDay() == null ? other.getCreateDay() == null : this.getCreateDay().equals(other.getCreateDay())) + && (this.getIsPostpone() == null ? other.getIsPostpone() == null : this.getIsPostpone().equals(other.getIsPostpone())); } @Override @@ -434,6 +454,7 @@ public class TbCallQueue implements Serializable { result = prime * result + ((getConfirmTime() == null) ? 0 : getConfirmTime().hashCode()); result = prime * result + ((getCallNum() == null) ? 0 : getCallNum().hashCode()); result = prime * result + ((getCreateDay() == null) ? 0 : getCreateDay().hashCode()); + result = prime * result + ((getIsPostpone() == null) ? 0 : getIsPostpone().hashCode()); return result; } @@ -462,6 +483,7 @@ public class TbCallQueue implements Serializable { sb.append(", confirmTime=").append(confirmTime); sb.append(", callNum=").append(callNum); sb.append(", createDay=").append(createDay); + sb.append(", isPostpone=").append(isPostpone); sb.append(", serialVersionUID=").append(serialVersionUID); sb.append("]"); return sb.toString(); diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/BaseCallTableDTO.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/BaseCallTableDTO.java new file mode 100644 index 0000000..cc5d193 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/BaseCallTableDTO.java @@ -0,0 +1,13 @@ +package com.chaozhanggui.system.cashierservice.entity.dto.calltable; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class BaseCallTableDTO { + @NotNull + private Integer callTableId; + @NotNull + private Integer shopId; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/CallQueueDTO.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/CallQueueDTO.java new file mode 100644 index 0000000..68e1254 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/CallQueueDTO.java @@ -0,0 +1,13 @@ +package com.chaozhanggui.system.cashierservice.entity.dto.calltable; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class CallQueueDTO{ + @NotNull + private Integer callQueueId; + @NotNull + private Integer shopId; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/CallTableDTO.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/CallTableDTO.java new file mode 100644 index 0000000..f0028f5 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/CallTableDTO.java @@ -0,0 +1,29 @@ +package com.chaozhanggui.system.cashierservice.entity.dto.calltable; + +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Data +public class CallTableDTO { + @NotNull + private Integer shopId; + @NotEmpty + private String name; + private String note; + @NotNull + @Min(1) + private Integer waitTime; + @NotBlank + private String prefix; + @NotNull + @Min(1) + private Integer start; + @Min(1) + private Integer nearNum; + private Integer isPostpone; + private Integer postponeNum; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/TakeNumberDTO.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/TakeNumberDTO.java new file mode 100644 index 0000000..4e843b2 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/TakeNumberDTO.java @@ -0,0 +1,18 @@ +package com.chaozhanggui.system.cashierservice.entity.dto.calltable; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Pattern; + +@EqualsAndHashCode(callSuper = true) +@Data +public class TakeNumberDTO extends BaseCallTableDTO{ + private Integer userId; + @NotEmpty + @Pattern(regexp = "^1\\d{10}$|^(0\\d{2,3}-?|\\(0\\d{2,3}\\))?[1-9]\\d{4,7}(-\\d{1,8})?$",message = "手机号码格式错误") + private String phone; + private String note; + private String name; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateCallQueueDTO.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateCallQueueDTO.java new file mode 100644 index 0000000..1411fcb --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateCallQueueDTO.java @@ -0,0 +1,15 @@ +package com.chaozhanggui.system.cashierservice.entity.dto.calltable; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import javax.validation.constraints.NotNull; + +@EqualsAndHashCode(callSuper = true) +@Data +@Getter +public class UpdateCallQueueDTO extends CallQueueDTO{ + @NotNull + private Integer state; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateCallTableDTO.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateCallTableDTO.java new file mode 100644 index 0000000..a47fa10 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateCallTableDTO.java @@ -0,0 +1,23 @@ +package com.chaozhanggui.system.cashierservice.entity.dto.calltable; + +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +@Data +public class UpdateCallTableDTO{ + @NotNull + private Integer callTableId; + @NotNull + private Integer shopId; + private String name; + private String note; + @Min(1) + private Integer waitTime; + private String prefix; + @Min(1) + private Integer start; + @Min(1) + private Integer nearNum; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateConfigDTO.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateConfigDTO.java new file mode 100644 index 0000000..5407939 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/dto/calltable/UpdateConfigDTO.java @@ -0,0 +1,16 @@ +package com.chaozhanggui.system.cashierservice.entity.dto.calltable; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class UpdateConfigDTO { + @NotNull + private Integer shopId; + private Integer isOnline; + private String bgCover; + private Integer isPostpone; + private Integer postponeNum; + private Integer nearNum; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/entity/vo/CallRecordVO.java b/src/main/java/com/chaozhanggui/system/cashierservice/entity/vo/CallRecordVO.java new file mode 100644 index 0000000..3a071bc --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/entity/vo/CallRecordVO.java @@ -0,0 +1,12 @@ +package com.chaozhanggui.system.cashierservice.entity.vo; + +import com.chaozhanggui.system.cashierservice.entity.TbCallQueue; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class CallRecordVO extends TbCallQueue { + private String note; + private Long sinceAt; +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallConfigMapper.java b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallConfigMapper.java index dc16448..4995d9b 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallConfigMapper.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallConfigMapper.java @@ -5,8 +5,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** * @author Administrator -* @description 针对表【tb_call_config】的数据库操作Mapper -* @createDate 2024-09-19 14:35:05 +* @description 针对表【tb_call_config(叫号配置表)】的数据库操作Mapper +* @createDate 2024-12-10 10:12:45 * @Entity com.chaozhanggui.system.cashierservice.entity.TbCallConfig */ public interface TbCallConfigMapper extends BaseMapper { diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallQueueMapper.java b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallQueueMapper.java index 07d6081..29e7cfe 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallQueueMapper.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallQueueMapper.java @@ -1,16 +1,23 @@ package com.chaozhanggui.system.cashierservice.mapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.chaozhanggui.system.cashierservice.entity.TbCallQueue; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.chaozhanggui.system.cashierservice.entity.vo.CallRecordVO; +import org.apache.ibatis.annotations.Select; /** * @author Administrator -* @description 针对表【tb_call_queue】的数据库操作Mapper -* @createDate 2024-09-19 14:35:05 +* @description 针对表【tb_call_queue(叫号排号表)】的数据库操作Mapper +* @createDate 2024-12-10 10:12:45 * @Entity com.chaozhanggui.system.cashierservice.entity.TbCallQueue */ public interface TbCallQueueMapper extends BaseMapper { + @Select("select a.*, b.note, TIMESTAMPDIFF(SECOND, a.create_time, NOW()) as since_at from tb_call_queue a " + + "left join tb_call_table b on a.call_table_id=b.id " + + "where a.shop_id=#{shopId} and a.state in (3, 2, 1) order by a.create_time desc") + Page selectCallRecord(Integer shopId, Integer callTableId, Page objectPage); } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallTableMapper.java b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallTableMapper.java index b84eb65..269ad1b 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallTableMapper.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/mapper/TbCallTableMapper.java @@ -5,8 +5,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** * @author Administrator -* @description 针对表【tb_call_table】的数据库操作Mapper -* @createDate 2024-09-19 14:35:05 +* @description 针对表【tb_call_table(叫号桌型表)】的数据库操作Mapper +* @createDate 2024-12-10 10:12:45 * @Entity com.chaozhanggui.system.cashierservice.entity.TbCallTable */ public interface TbCallTableMapper extends BaseMapper { diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallConfigService.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallConfigService.java new file mode 100644 index 0000000..12e5f23 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallConfigService.java @@ -0,0 +1,13 @@ +package com.chaozhanggui.system.cashierservice.service; + +import com.chaozhanggui.system.cashierservice.entity.TbCallConfig; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author Administrator +* @description 针对表【tb_call_config(叫号配置表)】的数据库操作Service +* @createDate 2024-12-10 10:12:45 +*/ +public interface TbCallConfigService extends IService { + +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallQueueService.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallQueueService.java new file mode 100644 index 0000000..7f305f3 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallQueueService.java @@ -0,0 +1,13 @@ +package com.chaozhanggui.system.cashierservice.service; + +import com.chaozhanggui.system.cashierservice.entity.TbCallQueue; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author Administrator +* @description 针对表【tb_call_queue(叫号排号表)】的数据库操作Service +* @createDate 2024-12-10 10:12:45 +*/ +public interface TbCallQueueService extends IService { + +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallService.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallService.java new file mode 100644 index 0000000..0f95df7 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallService.java @@ -0,0 +1,30 @@ +package com.chaozhanggui.system.cashierservice.service; + + +import com.chaozhanggui.system.cashierservice.entity.dto.calltable.*; + +public interface TbCallService { + Object add(CallTableDTO addCallTableDTO); + + Object update(UpdateCallTableDTO callTableDTO); + + Object delete(BaseCallTableDTO baseCallTableDTO); + + Object takeNumber(TakeNumberDTO takeNumber); + + Object call(CallQueueDTO callQueueDTO); + + Object updateInfo(UpdateCallQueueDTO updateCallQueueDTO); + + Object get(Integer page, Integer size, Integer shopId, Integer callTableId, Integer state); + + Object takeNumberCode(Integer shopId, Integer callTableId); + + Object getQueue(Integer shopId, Integer callTableId, Integer state, Integer page, Integer size); + + Object getCallRecord(Integer shopId, Integer callTableId, Integer page, Integer size); + + Object getConfig(Integer shopId); + + Object updateConfig(UpdateConfigDTO configDTO); +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallTableService.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallTableService.java new file mode 100644 index 0000000..9e067e6 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/TbCallTableService.java @@ -0,0 +1,13 @@ +package com.chaozhanggui.system.cashierservice.service; + +import com.chaozhanggui.system.cashierservice.entity.TbCallTable; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author Administrator +* @description 针对表【tb_call_table(叫号桌型表)】的数据库操作Service +* @createDate 2024-12-10 10:12:45 +*/ +public interface TbCallTableService extends IService { + +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallConfigServiceImpl.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallConfigServiceImpl.java new file mode 100644 index 0000000..70ed84c --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallConfigServiceImpl.java @@ -0,0 +1,22 @@ +package com.chaozhanggui.system.cashierservice.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.chaozhanggui.system.cashierservice.entity.TbCallConfig; +import com.chaozhanggui.system.cashierservice.service.TbCallConfigService; +import com.chaozhanggui.system.cashierservice.mapper.TbCallConfigMapper; +import org.springframework.stereotype.Service; + +/** +* @author Administrator +* @description 针对表【tb_call_config(叫号配置表)】的数据库操作Service实现 +* @createDate 2024-12-10 10:12:45 +*/ +@Service +public class TbCallConfigServiceImpl extends ServiceImpl + implements TbCallConfigService{ + +} + + + + diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallQueueServiceImpl.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallQueueServiceImpl.java new file mode 100644 index 0000000..6058a5e --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallQueueServiceImpl.java @@ -0,0 +1,22 @@ +package com.chaozhanggui.system.cashierservice.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.chaozhanggui.system.cashierservice.entity.TbCallQueue; +import com.chaozhanggui.system.cashierservice.service.TbCallQueueService; +import com.chaozhanggui.system.cashierservice.mapper.TbCallQueueMapper; +import org.springframework.stereotype.Service; + +/** +* @author Administrator +* @description 针对表【tb_call_queue(叫号排号表)】的数据库操作Service实现 +* @createDate 2024-12-10 10:12:45 +*/ +@Service +public class TbCallQueueServiceImpl extends ServiceImpl + implements TbCallQueueService{ + +} + + + + diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallServiceImpl.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallServiceImpl.java new file mode 100644 index 0000000..9b3286f --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallServiceImpl.java @@ -0,0 +1,575 @@ +package com.chaozhanggui.system.cashierservice.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.qrcode.QrCodeUtil; +import cn.hutool.extra.qrcode.QrConfig; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.chaozhanggui.system.cashierservice.dao.TbShopInfoMapper; +import com.chaozhanggui.system.cashierservice.dao.TbShopUserMapper; +import com.chaozhanggui.system.cashierservice.entity.*; +import com.chaozhanggui.system.cashierservice.entity.dto.calltable.*; +import com.chaozhanggui.system.cashierservice.exception.MsgException; +import com.chaozhanggui.system.cashierservice.mapper.TbCallQueueMapper; +import com.chaozhanggui.system.cashierservice.mybatis.MpShopUserMapper; +import com.chaozhanggui.system.cashierservice.service.TbCallConfigService; +import com.chaozhanggui.system.cashierservice.service.TbCallQueueService; +import com.chaozhanggui.system.cashierservice.service.TbCallService; +import com.chaozhanggui.system.cashierservice.service.TbCallTableService; +import com.chaozhanggui.system.cashierservice.util.RabbitMsgUtils; +import com.chaozhanggui.system.cashierservice.util.RedisCst; +import com.chaozhanggui.system.cashierservice.util.Utils; +import com.chaozhanggui.system.cashierservice.util.WxAccountUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayOutputStream; +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +@Service +public class TbCallServiceImpl implements TbCallService { + + @Value("${wx.mini.page.call}") + private String callPageUrl; + + private final TbCallTableService callTableService; + private final TbCallQueueService callQueueService; + private final MpShopUserMapper shopUserMapper; + private final TbShopInfoMapper shopInfoMapper; + private final StringRedisTemplate redisTemplate; + private final TbCallQueueMapper tbCallQueueMapper; + private final WxAccountUtil wxMiniUtils; + private final TbCallConfigService tbCallConfigService; + private final RabbitMsgUtils rabbitMsgUtils; + + public TbCallServiceImpl(TbCallTableService callTableService, TbCallQueueService callQueueService, + MpShopUserMapper shopUserMapper, TbShopInfoMapper shopInfoMapper, + StringRedisTemplate redisTemplate, TbCallQueueMapper tbCallQueueMapper, + WxAccountUtil wxMiniUtils, TbCallConfigService tbCallConfigService, RabbitMsgUtils rabbitMsgUtils) { + this.callTableService = callTableService; + this.callQueueService = callQueueService; + this.shopUserMapper = shopUserMapper; + this.shopInfoMapper = shopInfoMapper; + this.redisTemplate = redisTemplate; + this.tbCallQueueMapper = tbCallQueueMapper; + this.wxMiniUtils = wxMiniUtils; + this.tbCallConfigService = tbCallConfigService; + this.rabbitMsgUtils = rabbitMsgUtils; + } + + @Override + public Object add(CallTableDTO addCallTableDTO) { + Integer count = callTableService.lambdaQuery() + .eq(TbCallTable::getShopId, addCallTableDTO.getShopId()) + .and(q -> q.eq(TbCallTable::getName, addCallTableDTO.getName()) + .or() + .eq(TbCallTable::getPrefix, addCallTableDTO.getPrefix())).count(); + if (count > 0) { + throw new MsgException("名称或前缀已存在"); + } + + TbCallTable callTable = new TbCallTable(); + BeanUtil.copyProperties(addCallTableDTO, callTable); + callTable.setCreateTime(DateUtil.date()); + return callTableService.save(callTable); + } + + @Override + public Object update(UpdateCallTableDTO callTableDTO) { + TbCallTable callTable = callTableService.lambdaQuery() + .eq(TbCallTable::getShopId, callTableDTO.getShopId()) + .eq(TbCallTable::getId, callTableDTO.getCallTableId()).one(); + + if (callTable == null) { + throw new MsgException("桌型不存在"); + } + TbCallTable newInfo = new TbCallTable(); + BeanUtil.copyProperties(callTableDTO, newInfo); + newInfo.setId(callTable.getId()); + newInfo.setUpdateTime(DateUtil.date()); + + return callTableService.updateById(newInfo); + } + + @Override + public Object delete(BaseCallTableDTO baseCallTableDTO) { + return callTableService.remove(new LambdaQueryWrapper() + .eq(TbCallTable::getId, baseCallTableDTO.getCallTableId()) + .eq(TbCallTable::getShopId, baseCallTableDTO.getShopId())); + } + + private String getCallNumber(Integer shopId, TbCallTable callTable) { + return Utils.runFunAndCheckKey(() -> { + String callNumKey = RedisCst.getTableCallNumKey(shopId, callTable.getId()); + String value = redisTemplate.opsForValue().get(callNumKey); + AtomicReference newVal = new AtomicReference<>(""); + // 初始化 + if (StrUtil.isBlank(value)) { + Boolean setFlag = Utils.runFunAndRetry(() -> redisTemplate.opsForValue().setIfAbsent(callNumKey, callTable.getStart().toString()), flag -> !flag, + r -> newVal.set(redisTemplate.opsForValue().get(callNumKey))); + + if (setFlag) { + return callTable.getPrefix() + callTable.getStart(); + }else if (StrUtil.isNotBlank(newVal.get())){ + value = String.valueOf((Integer.parseInt(newVal.get()) + 1)); + redisTemplate.opsForValue().set(callNumKey, value); + return callTable.getPrefix() + value; + }else { + throw new MsgException("生成排队号码失败"); + } + + }else { + value = String.valueOf((Integer.parseInt(value) + 1)); + redisTemplate.opsForValue().set(callNumKey, value); + return callTable.getPrefix() + value; + } + }, redisTemplate, RedisCst.getLockKey("UPDATE_TABLE", shopId, callTable.getId())); + + } + + @Override + public Object takeNumber(TakeNumberDTO takeNumberDTO) { + TbShopInfo shopInfo = shopInfoMapper.selectByPrimaryKey(takeNumberDTO.getShopId()); + if (shopInfo == null) { + throw new MsgException("店铺信息不存在"); + } + + TbCallTable callTable = callTableService.lambdaQuery() + .eq(TbCallTable::getShopId, takeNumberDTO.getShopId()) + .eq(TbCallTable::getId, takeNumberDTO.getCallTableId()).one(); + if (callTable == null) { + throw new MsgException("桌型不存在"); + } + + // 查询当前 + + // 拿取系统内部用户信息 + TbCallQueue callQueue; + if (takeNumberDTO.getUserId() != null) { + TbShopUser shopUser = shopUserMapper.selectOne(new LambdaQueryWrapper() + .eq(TbShopUser::getStatus, 1) + .eq(TbShopUser::getShopId, takeNumberDTO.getShopId()) + .eq(TbShopUser::getId, takeNumberDTO.getUserId())); + if (shopUser == null) { + throw new MsgException("用户不存在"); + } + + callQueue = callQueueService.lambdaQuery() + .eq(TbCallQueue::getUserId, shopUser.getId()) + .eq(TbCallQueue::getShopId, takeNumberDTO.getShopId()) + .in(TbCallQueue::getState, 0, 1) + .eq(TbCallQueue::getCreateDay, DateUtil.today()) + .ne(TbCallQueue::getIsPostpone, 2) + .eq(TbCallQueue::getCallTableId, takeNumberDTO.getCallTableId()).one(); + if (callQueue != null) { + throw new MsgException("当前用户已取号"); + } + + callQueue = new TbCallQueue(); + BeanUtil.copyProperties(takeNumberDTO, callQueue); + callQueue.setPhone(StrUtil.isBlank(takeNumberDTO.getPhone()) ? shopUser.getTelephone() : takeNumberDTO.getPhone()); + +// callQueue.setOpenId(shopUser.getMiniOpenId()); + + }else { +// if (StrUtil.isBlank(takeNumberDTO.getPhone()) || StrUtil.isBlank(takeNumberDTO.getOpenId())) { +// throw new MsgException("手机号或openId不能为空"); +// } + + callQueue = callQueueService.lambdaQuery() + .eq(TbCallQueue::getPhone, takeNumberDTO.getPhone()) + .eq(TbCallQueue::getShopId, takeNumberDTO.getShopId()) + .eq(TbCallQueue::getCreateDay, DateUtil.today()) + .in(TbCallQueue::getState, 0, 1) + .ne(TbCallQueue::getIsPostpone, 2) + .eq(TbCallQueue::getCallTableId, takeNumberDTO.getCallTableId()).one(); + if (callQueue != null) { + throw new MsgException("当前用户已取号"); + } + + callQueue = new TbCallQueue(); + BeanUtil.copyProperties(takeNumberDTO, callQueue); + callQueue.setPhone(takeNumberDTO.getPhone()); +// callQueue.setOpenId(takeNumberDTO.getOpenId()); + callQueue.setSubState(0); + } + + callQueue.setCreateDay(DateUtil.today()); + callQueue.setCallNum(getCallNumber(takeNumberDTO.getShopId(), callTable)); + callQueue.setCreateTime(DateUtil.date()); + callQueue.setShopId(shopInfo.getId()); + callQueue.setShopName(shopInfo.getShopName()); + + callQueueService.save(callQueue); + + // 打印排号票信息 + rabbitMsgUtils.printCallNumTicket(callQueue.getId(), callQueue.getShopId()); + + HashMap data = new HashMap<>(); + data.put("tableName", callTable.getName()); + data.put("tableNote", callTable.getNote()); + data.put("callNum", callQueue.getCallNum()); + return data; + } + + @Override + public Object call(CallQueueDTO callQueueDTO) { + TbCallQueue callQueue = callQueueService.lambdaQuery() + .notIn(TbCallQueue::getState, -1, 2) + .eq(TbCallQueue::getCreateDay, DateUtil.today()) + .eq(TbCallQueue::getId, callQueueDTO.getCallQueueId()) + .eq(TbCallQueue::getShopId, callQueueDTO.getShopId()) + .one(); + + if (callQueue == null) { + throw new MsgException("叫号用户不存在"); + } + + callQueue.setState(1); + callQueue.setCallCount(callQueue.getCallCount() + 1); + callQueue.setCallTime(DateUtil.date()); + callQueueService.updateById(callQueue); + + if (callQueue.getSubState().equals(0)) { + return new HashMap(){{ + put("state", "-1"); + }}; + } + + // 发送模板消息通知用户 + + TbShopInfo shopInfo = shopInfoMapper.selectByPrimaryKey(callQueue.getShopId()); + if (shopInfo == null) { + throw new MsgException("店铺信息不存在"); + } + + List current = callQueueService.lambdaQuery() + .eq(TbCallQueue::getCallTableId, callQueue.getCallTableId()) + .eq(TbCallQueue::getCreateDay, DateUtil.today()) + .and(r -> { + r.eq(TbCallQueue::getState, 1) + .or() + .eq(TbCallQueue::getState, 0); + }) + .orderByAsc(TbCallQueue::getCreateTime) + .page(new Page<>(1, 1)).getRecords(); + + + if (StrUtil.isBlank(callQueue.getOpenId())) { + return new HashMap(){{ + put("state", "-1"); + }}; + } + + wxMiniUtils.sendCurrentOrNearCallMsg(shopInfo.getShopName(), getStrByState(Integer.valueOf(callQueue.getState())), + callQueue.getCallNum(), current.isEmpty() ? "" : current.get(0).getCallNum(), "排号信息", callQueue.getOpenId(), false); + + TbCallConfig config = getConfig(callQueueDTO.getShopId()); + // 临近用户提醒 + List nearList = callQueueService.lambdaQuery() + .eq(TbCallQueue::getCallTableId, callQueue.getCallTableId()) + .eq(TbCallQueue::getCreateDay, DateUtil.today()) + .gt(TbCallQueue::getId, current.get(0).getId()) + .page(new Page<>(config.getNearNum(), 1)).getRecords(); + if (!nearList.isEmpty()) { + TbCallQueue nearQueue = nearList.get(0); + wxMiniUtils.sendCurrentOrNearCallMsg(shopInfo.getShopName(), getStrByState(Integer.valueOf(nearQueue.getState())), + nearQueue.getCallNum(), current.isEmpty() ? "" : current.get(0).getCallNum(), "排号信息", nearQueue.getOpenId(), true); + } + return new HashMap(){{ + put("state", "1"); + }}; + } + + private String getStrByState(Integer state) { + String msg = ""; + switch (state) { + case -1: + msg = "已取消"; + break; + case 0: + msg = "排队中"; + break; + case 1: + msg = "已到号"; + break; + case 3: + msg = "已过号"; + } + + return msg; + } + + @Override + public Object updateInfo(UpdateCallQueueDTO updateCallQueueDTO) { + TbCallQueue callQueue = callQueueService.lambdaQuery() + .eq(TbCallQueue::getShopId, updateCallQueueDTO.getShopId()) + .eq(TbCallQueue::getCreateDay, DateUtil.today()) + .eq(TbCallQueue::getId, updateCallQueueDTO.getCallQueueId()).one(); + if (callQueue == null) { + throw new MsgException("叫号用户不存在"); + } + + switch (updateCallQueueDTO.getState()) { + case -1: + callQueue.setCancelTime(DateUtil.date()); + break; + case 0: + callQueue.setState(0); + break; + case 1: + if (callQueue.getSubState().equals(0)) { + throw new MsgException("当前用户未订阅微信提醒"); + } + callQueue.setState(1); + callQueue.setCallCount(callQueue.getCallCount() + 1); + callQueue.setCallTime(DateUtil.date()); + break; + case 2: + callQueue.setConfirmTime(DateUtil.date()); + break; + case 3: + callQueue.setPassTime(DateUtil.date()); + // 已经顺延 + callQueue.setIsPostpone(callQueue.getIsPostpone() == null ? 1 : callQueue.getIsPostpone() == 0 ? 1 : 2); + TbShopInfo shopInfo = shopInfoMapper.selectByPrimaryKey(callQueue.getShopId()); + if (shopInfo == null) { + throw new MsgException("店铺信息不存在"); + } + + if(StrUtil.isBlank(callQueue.getOpenId()) && callQueue.getSubState() != 1) { + break; + } + + TbCallTable callTable = callTableService.getById(callQueue.getCallTableId()); + Integer isPostpone = callTable.getIsPostpone(); + Integer postponeNum = callTable.getPostponeNum(); + + // 判断是否需要顺延, 暂时注释 + if (false && callQueue.getIsPostpone() == 0 && isPostpone != null && isPostpone == 1 && postponeNum != null && postponeNum > 0) { + // 查询当前桌以及顺延桌数 + List current = callQueueService.lambdaQuery() + .eq(TbCallQueue::getCallTableId, callQueue.getCallTableId()) + .eq(TbCallQueue::getCreateDay, DateUtil.today()) + .eq(TbCallQueue::getShopId, callTable.getShopId()) + .ge(TbCallQueue::getId, callQueue.getId()) + .orderByAsc(TbCallQueue::getCreateTime) + .page(new Page<>(1, postponeNum + 1)) // 获取当前桌和顺延的桌数 + .getRecords(); + + // 确保有足够的桌可以顺延 + if (current.size() > 1) { + // 获取当前桌以及顺延桌 + TbCallQueue currentTable = new TbCallQueue(); + BeanUtil.copyProperties(current.get(0), currentTable); + // 顺延替换信息,将每一张顺延桌向前移动 + for (int i = 0; i < current.size() - 1; i++) { + exchangeCallQueueInfo(current.get(i), current.get(i + 1)); // 当前桌替换为顺延桌 + } + + exchangeCallQueueInfo(current.get(current.size() - 1), currentTable); + callQueue = current.get(current.size() - 1); + + // 更新数据库中的桌号信息 + callQueueService.updateBatchById(current); + } + } + + List current = callQueueService.lambdaQuery() + .eq(TbCallQueue::getCallTableId, callQueue.getCallTableId()) + .eq(TbCallQueue::getCreateDay, DateUtil.today()) + .and(r -> { + r.eq(TbCallQueue::getState, 1) + .or() + .eq(TbCallQueue::getState, 0); + }) + .orderByAsc(TbCallQueue::getCreateTime) + .page(new Page<>(1, 1)).getRecords(); + wxMiniUtils.sendPassCallMsg(shopInfo.getShopName(), getStrByState(Integer.valueOf(updateCallQueueDTO.getState())), + callQueue.getCallNum(), current.isEmpty() ? "" : current.get(0).getCallNum(), "即将过号", callQueue.getOpenId()); + break; + default: + throw new MsgException("错误类型"); + + } + + callQueue.setState(updateCallQueueDTO.getState()); + + return callQueueService.updateById(callQueue); + } + + private void exchangeCallQueueInfo(TbCallQueue setCallQueue, TbCallQueue copyCallQueue) { + setCallQueue.setOpenId(copyCallQueue.getOpenId()); + setCallQueue.setState(copyCallQueue.getState()); + setCallQueue.setSubState(copyCallQueue.getSubState()); + setCallQueue.setCreateTime(copyCallQueue.getCreateTime()); + setCallQueue.setName(copyCallQueue.getName()); + setCallQueue.setNote(copyCallQueue.getNote()); + setCallQueue.setCallNum(copyCallQueue.getCallNum()); + setCallQueue.setCallTime(copyCallQueue.getCallTime()); + setCallQueue.setCallCount(copyCallQueue.getCallCount()); + setCallQueue.setPassTime(copyCallQueue.getPassTime()); + setCallQueue.setCancelTime(copyCallQueue.getCancelTime()); + setCallQueue.setUserId(copyCallQueue.getUserId()); + setCallQueue.setConfirmTime(copyCallQueue.getConfirmTime()); + + } + + @Override + public Object get(Integer page, Integer size, Integer shopId, Integer callTableId, Integer state) { + LambdaQueryWrapper query = new LambdaQueryWrapper() + .eq(TbCallTable::getShopId, shopId) + .eq(TbCallTable::getState, 1); + + if (callTableId != null) { + query.eq(TbCallTable::getId, callTableId); + } + + if (state != null) { + query.eq(TbCallTable::getState, state); + } + Page pageInfo = callTableService.page(new Page<>(page, size), query); + ArrayList> info = new ArrayList<>(); + Long totalCount = 0L; + for (TbCallTable item : pageInfo.getRecords()) { + LambdaQueryChainWrapper q = callQueueService.lambdaQuery() + .eq(TbCallQueue::getCallTableId, item.getId()) + .eq(TbCallQueue::getShopId, shopId) + .eq(TbCallQueue::getCreateDay, DateUtil.today()) + .in(TbCallQueue::getState, 0, 1); + Integer count = q.count(); + + totalCount += count; + + Map map = BeanUtil.beanToMap(item, false, false); + map.put("totalCount", count); + map.put("isPostpone", item.getIsPostpone() == 1); + info.add(map); + } + + Map toMap = BeanUtil.beanToMap(pageInfo); + toMap.put("records", info); + toMap.put("totalCount", totalCount); + return toMap; + } + + @Override + public Object takeNumberCode(Integer shopId, Integer callTableId) { + // 创建二维码配置对象,设置宽度和高度为400 + QrConfig config = new QrConfig(400, 400); + + // 使用字节数组输出流来存储二维码图片 + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + // 生成二维码图片,输出到字节数组输出流 + QrCodeUtil.generate(StrUtil.format(callPageUrl, shopId, ""), config, "png", outputStream); + + // 将图片转换为 Base64 字符串 + String base64 = Base64.getEncoder().encodeToString(outputStream.toByteArray()); + + // 返回Base64格式的图片字符串 + return "data:image/png;base64," + base64; + } + + @Override + public Object getQueue(Integer shopId, Integer callTableId, Integer state, Integer page, Integer size) { + List tableIds; + if (callTableId != null) { + tableIds = Collections.singletonList(callTableId); + }else { + List list = callTableService.lambdaQuery() + .eq(TbCallTable::getShopId, shopId) + .eq(TbCallTable::getState, 1).list(); + if (list.isEmpty()) { + return new Page<>(); + } + tableIds = list.stream() + .map(TbCallTable::getId) + .collect(Collectors.toList()); + } + + LambdaQueryChainWrapper query = callQueueService.lambdaQuery() + .eq(TbCallQueue::getShopId, shopId) + .eq(TbCallQueue::getCreateDay, DateUtil.today()) + .in(TbCallQueue::getCallTableId, tableIds); + state = null; + if (state != null) { + query.eq(TbCallQueue::getState, state); + }else { + query.in(TbCallQueue::getState, 0, 1); + } + Page pageInfo = query + .orderByAsc(TbCallQueue::getCreateTime) + .orderByDesc(TbCallQueue::getState) + .page(new Page<>(page, size)); + + List list1 = pageInfo.getRecords(); + + // 创建返回的结果集 + List> resultList = new ArrayList<>(); + + // 遍历每一个叫号中的记录,计算前面状态为"0" (排队中) 的人数 + for (TbCallQueue calling : list1) { + // 计算前面等待的人数 (状态为"0"且在叫号记录创建时间之前的) + long waitingCount = 0; + if (calling.getState() == 0) { + waitingCount = list1.stream() + .filter(item -> item.getState() == 0 || item.getState() == 1) // 过滤出状态为"排队中"的 + .filter(item -> item.getCreateTime().compareTo(calling.getCreateTime()) < 0 ) // 时间在当前叫号之前 + .count(); + } + + // 创建一个Map来保存叫号中的记录及其前面排队的人数 + Map map = BeanUtil.beanToMap(calling, false, false); + map.put("waitingCount", waitingCount); + // 将该map加入结果集 + resultList.add(map); + } + + Map toMap = BeanUtil.beanToMap(pageInfo, false, false); + toMap.put("records", resultList); + + // 返回结果列表 + return toMap; + } + + @Override + public Object getCallRecord(Integer shopId, Integer callTableId, Integer page, Integer size) { + return tbCallQueueMapper.selectCallRecord(shopId, callTableId, new Page<>(page, size)); + } + + @Override + public TbCallConfig getConfig(Integer shopId) { + TbCallConfig config = tbCallConfigService.lambdaQuery().eq(TbCallConfig::getShopId, shopId).one(); + if (config == null) { + config = new TbCallConfig(); + config.setShopId(shopId); + config.setCreateTime(DateUtil.date()); + tbCallConfigService.save(config); + config = tbCallConfigService.lambdaQuery().eq(TbCallConfig::getShopId, shopId).one(); + } + + return config; + } + + @Override + public Object updateConfig(UpdateConfigDTO configDTO) { + TbCallConfig config = tbCallConfigService.lambdaQuery().eq(TbCallConfig::getShopId, configDTO.getShopId()).one(); + if (config == null) { + throw new MsgException("未查询到配置信息"); + } + + TbCallConfig tbCallConfig = new TbCallConfig(); + BeanUtil.copyProperties(configDTO, tbCallConfig); + tbCallConfig.setId(config.getId()); + tbCallConfig.setUpdateTime(DateUtil.date()); + return tbCallConfigService.updateById(tbCallConfig); + } + +} diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallTableServiceImpl.java b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallTableServiceImpl.java new file mode 100644 index 0000000..e6be3f2 --- /dev/null +++ b/src/main/java/com/chaozhanggui/system/cashierservice/service/impl/TbCallTableServiceImpl.java @@ -0,0 +1,22 @@ +package com.chaozhanggui.system.cashierservice.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.chaozhanggui.system.cashierservice.entity.TbCallTable; +import com.chaozhanggui.system.cashierservice.service.TbCallTableService; +import com.chaozhanggui.system.cashierservice.mapper.TbCallTableMapper; +import org.springframework.stereotype.Service; + +/** +* @author Administrator +* @description 针对表【tb_call_table(叫号桌型表)】的数据库操作Service实现 +* @createDate 2024-12-10 10:12:45 +*/ +@Service +public class TbCallTableServiceImpl extends ServiceImpl + implements TbCallTableService{ + +} + + + + diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/util/RabbitMsgUtils.java b/src/main/java/com/chaozhanggui/system/cashierservice/util/RabbitMsgUtils.java index e19da2d..8d87a20 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/util/RabbitMsgUtils.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/util/RabbitMsgUtils.java @@ -2,6 +2,7 @@ package com.chaozhanggui.system.cashierservice.util; import com.alibaba.fastjson.JSONObject; import com.chaozhanggui.system.cashierservice.entity.TbOrderDetail; +import com.chaozhanggui.system.cashierservice.entity.dto.CallNumPrintDTO; import com.chaozhanggui.system.cashierservice.rabbit.RabbitConstants; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.connection.CorrelationData; @@ -80,4 +81,20 @@ public class RabbitMsgUtils implements RabbitTemplate.ConfirmCallback { public void updateCons(JSONObject jsonObject1) { sendMsg(RabbitConstants.EXCHANGE_CONS, RabbitConstants.ROUTING_KEY_CONS, jsonObject1, "储值卡记录", true); } + + public void printCallNumTicket(Integer callQueueId, Integer shopId) { + CallNumPrintDTO printDTO = new CallNumPrintDTO(); + printDTO.setCallQueueId(callQueueId); + printDTO.setShopId(shopId); + try { + JSONObject currentUserInfo = TokenUtil.getCurrentUserInfo(); + log.info("用户信息: {}", currentUserInfo); + printDTO.setCurrentUserId(currentUserInfo.getLong("accountId")); + printDTO.setCurrentUserName(currentUserInfo.getString("name")); + printDTO.setCurrentUserNickName(currentUserInfo.getString("nickname")); + } catch (Exception e) { + log.error("获取当前用户信息失败", e); + } + sendMsg(RabbitConstants.EXCHANGE_PRINT, RabbitConstants.ROUTING_KEY_CALL_TABLE, printDTO, "排号小票打印", true); + } } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/util/RedisCst.java b/src/main/java/com/chaozhanggui/system/cashierservice/util/RedisCst.java index ede9bb9..55be804 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/util/RedisCst.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/util/RedisCst.java @@ -30,7 +30,8 @@ public class RedisCst { // 选择人数锁 public static final String CHOSE_TABLE_COUNT = "CHOSE_TABLE_COUNT"; - + // 排队取号全局号码 + static String TABLE_CALL_NUMBER = "TABLE_CALL_NUMBER:"; public static String getCurrentOrderKey(String tableId, String shopId) { @@ -50,4 +51,8 @@ public class RedisCst { } return key.toString(); } + + public static String getTableCallNumKey(Integer shopId, Integer callTableId) { + return TABLE_CALL_NUMBER + shopId + ":" + callTableId; + } } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/util/TokenUtil.java b/src/main/java/com/chaozhanggui/system/cashierservice/util/TokenUtil.java index 286d119..32b3949 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/util/TokenUtil.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/util/TokenUtil.java @@ -7,7 +7,10 @@ import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.cglib.beans.BeanMap; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import javax.servlet.http.HttpServletRequest; import java.text.SimpleDateFormat; import java.util.*; @@ -106,4 +109,11 @@ public class TokenUtil { public static void main(String[] args) { parseParamFromToken("eyJhbGciOiJIUzI1NiJ9.eyJhY2NvdW50SWQiOiI2IiwiY2xpZW50VHlwZSI6InBjIiwic2hvcElkIjoiMTUiLCJleHAiOjE3MTA1ODc3NjAsImlhdCI6MTcwOTExNjUzMSwibG9naW5OYW1lIjoiMTg4MjE3Nzc4OCJ9.RXfyRgkfC13JGVypd9TQvbNNl_-btyQ-7xnvlj3ej0M"); } + + public static JSONObject getCurrentUserInfo() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = attributes.getRequest(); + String token = request.getHeader("token"); + return parseParamFromToken(token); + } } diff --git a/src/main/java/com/chaozhanggui/system/cashierservice/util/WxAccountUtil.java b/src/main/java/com/chaozhanggui/system/cashierservice/util/WxAccountUtil.java index 461531e..b9369ea 100644 --- a/src/main/java/com/chaozhanggui/system/cashierservice/util/WxAccountUtil.java +++ b/src/main/java/com/chaozhanggui/system/cashierservice/util/WxAccountUtil.java @@ -31,6 +31,12 @@ public class WxAccountUtil { private final TbShopMsgStateMapper shopMsgStateMapper; static LinkedHashMap linkedHashMap=new LinkedHashMap<>(); + + @Value("${wx.mini.user.msgId.currentCall}") + private String currentCallTempId; + @Value("${wx.mini.user.msgId.nearCall}") + private String nearCallTempId; + static { linkedHashMap.put("40001","获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口"); @@ -132,4 +138,76 @@ public class WxAccountUtil { return null; } } + + public void sendCurrentOrNearCallMsg(String shopName, String state, String callNum, String currentNum, String note, String openId, boolean isNear) { + Map data = new HashMap() {{ + put("thing1", new HashMap() {{ + put("value", shopName); + }}); + put("phrase2", new HashMap() {{ + put("value", state); + }}); + put("character_string3", new HashMap() {{ + put("value", callNum); + }}); + put("character_string4", new HashMap() {{ + put("value", currentNum); + }}); + put("thing5", new HashMap() {{ + put("value", note); + }}); + }}; + try { + sendTempMsg(isNear ? nearCallTempId : currentCallTempId, openId, data, "排队到号"); + } catch (Exception e) { + log.error("发送失败, openId:{}, msg: {}", openId, e.getMessage()); + } + } + + public JSONObject sendTempMsg(String tempId, String toUserOpenId, Map data, String note) { + log.info("开始发送" + note + "模板消息, 接收用户openId: {}, 消息数据: {}", toUserOpenId, data); + String accessToken= getAccessToken(); + JSONObject object1=new JSONObject(); + + object1.put("template_id", tempId); + object1.put("touser", toUserOpenId); + object1.put("data",data); + + object1.put("miniprogram_state","trial"); + object1.put("lang","zh_CN"); + + String response= HttpRequest.post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=".concat(accessToken)).body(object1.toString()).execute().body(); + log.info("微信模板消息发送成功,相应内容:{}",response); + JSONObject resObj=JSONObject.parseObject(response); + if(ObjectUtil.isNotEmpty(resObj)&&ObjectUtil.isNotNull(resObj)&&"0".equals(resObj.get("errcode")+"")){ + return resObj; + } + + throw new RuntimeException(linkedHashMap.getOrDefault(resObj.get("errcode") + "", "未知错误")); + } + + public void sendPassCallMsg(String shopName, String state, String callNum, String currentNum, String note, String openId) { + Map data = new HashMap() {{ + put("thing1", new HashMap() {{ + put("value", shopName); + }}); + put("character_string2", new HashMap() {{ + put("value", callNum); + }}); + put("character_string3", new HashMap() {{ + put("value", currentNum); + }}); + put("phrase4", new HashMap() {{ + put("value", state); + }}); + put("thing5", new HashMap() {{ + put("value", note); + }}); + }}; + try { + sendTempMsg(currentCallTempId, openId, data, "过号"); + } catch (Exception e) { + log.error("发送失败, openId:{}, msg: {}", openId, e.getMessage()); + } + } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3a5fa0c..7ce97ff 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -60,6 +60,13 @@ wx: secrete: a34a61adc0602118b49400baa8812454 warnMsgTmpId: AV-KybUHaK3KtFVLqpy6PHccHBS7XeX__mOM4RbufnQ mini: + user: + appId: wxd88fffa983758a30 + secrete: a34a61adc0602118b49400baa8812454 + msgId: + nearCall: yxOjWK-KjMEZ_BaHWqDJJpHiUPXN6JWqr7u9y65RIWM + currentCall: 3BgFazRpVlvreh5z9u4cNP_VeclXKSQfh-r3x2_bYx4 + passCall: qUhvEfvCtIcBA3DOn3QMqsGOolrEpyr0YBh99i-AUqw page: call: https://cashier.sxczgkj.cn/make?shopId={}&queueId={} ali: diff --git a/src/main/resources/mapper/TbCallConfigMapper.xml b/src/main/resources/mapper/TbCallConfigMapper.xml index c26eaa9..6d74f99 100644 --- a/src/main/resources/mapper/TbCallConfigMapper.xml +++ b/src/main/resources/mapper/TbCallConfigMapper.xml @@ -15,14 +15,13 @@ - - + id,page_address,is_online, bg_cover,success_msg,near_msg, calling_msg,shop_id,create_time, - update_time,is_postpone,postpone_num + update_time,near_num diff --git a/src/main/resources/mapper/TbCallQueueMapper.xml b/src/main/resources/mapper/TbCallQueueMapper.xml index 77e10fe..c89c469 100644 --- a/src/main/resources/mapper/TbCallQueueMapper.xml +++ b/src/main/resources/mapper/TbCallQueueMapper.xml @@ -24,6 +24,7 @@ + @@ -33,6 +34,6 @@ call_count,pass_time,cancel_time, note,user_id,open_id, sub_state,confirm_time,call_num, - create_day + create_day,is_postpone diff --git a/src/main/resources/mapper/TbCallTableMapper.xml b/src/main/resources/mapper/TbCallTableMapper.xml index 2e1f86e..365645f 100644 --- a/src/main/resources/mapper/TbCallTableMapper.xml +++ b/src/main/resources/mapper/TbCallTableMapper.xml @@ -17,12 +17,15 @@ + + id,name,note, wait_time,prefix,start, near_num,state,shop_id, - qrcode,create_time,update_time + qrcode,create_time,update_time, + is_postpone,postpone_num