Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
牛叉闪闪 2024-08-14 15:08:48 +08:00
commit 5fe0e2a83b
61 changed files with 2382 additions and 156 deletions

View File

@ -74,4 +74,6 @@ public interface CacheKey {
*/
String PRODUCT = "PRODUCT:";
String SONG_URL = "song:";
String VIPCODE = "VIPCODE:";
}

View File

@ -41,6 +41,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* File工具类扩展 hutool 工具包
@ -270,7 +271,7 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
}
}
public static void downloadExcelAndMerge(List<Map<String, Object>> list, int colSize, HttpServletResponse response, ArrayList<Integer> mergeRowIndex) throws IOException {
public static void downloadExcelAndMerge(ConcurrentLinkedQueue<Map<String, Object>> list, int colSize, HttpServletResponse response, List<Integer> mergeRowIndex) throws IOException {
String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx";
File file = new File(tempPath);
ExcelWriter writer = ExcelUtil.getWriter(file);

View File

@ -257,6 +257,15 @@ public class RedisUtils {
}
}
public boolean setNx(String key, Object value) {
try {
return redisTemplate.opsForValue().setIfAbsent(key, value);
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
}
}
/**
* 普通缓存放入并设置时间
*

View File

@ -19,6 +19,10 @@
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- 代码生成模块 -->
<dependency>

View File

@ -105,6 +105,7 @@ public class TokenProvider implements InitializingBean {
.getBody();
}
/**
* @param token 需要检查的token
*/
@ -137,4 +138,17 @@ public class TokenProvider implements InitializingBean {
}
return null;
}
public String getSubject() {
HttpServletRequest request = SpringContextHolder.getRequest();
final String requestHeader = request.getHeader(properties.getHeader());
if (requestHeader != null && requestHeader.startsWith(properties.getTokenStartWith())) {
Claims claims = jwtParser
.parseClaimsJws(requestHeader.substring(7))
.getBody();
return claims.getSubject();
}
return null;
}
}

View File

@ -0,0 +1,15 @@
package cn.ysk.cashier.cons;
public interface RedisConstant {
//在线用户
String ONLINE_USER = "ONLINE:USER";
String CART = "CZG:CART:";
public final Object PRODUCT = "PRODUCT:";
public final String OUT_NUMBER="ORDER:NUMBER:";
public static final String ORDER_MESSAGE="ORDER:MESSAGE:";
public static final String ORDER_PRODUCT_NUM = "ORDER_NUM:";
public static final String ORDER_CART_EXISTS = "ORDER_CART_EXISTS:";
}

View File

@ -5,4 +5,6 @@ public interface RabbitConstants {
String CONS_COLLECT_ROUTINGKEY_PUT = "cons_collect_routingkey_put";
String CONS_MSG_COLLECT_PUT = "cons_msg_collect_put";
String CONS_MSG_COLLECT_ROUTINGKEY_PUT = "cons_msg_collect_routingkey_put";
}

View File

@ -5,6 +5,7 @@ import cn.ysk.cashier.cons.domain.TbConsInfo;
import cn.ysk.cashier.cons.domain.TbConsInfoFlow;
import cn.ysk.cashier.cons.repository.TbConsInfoFlowRepository;
import cn.ysk.cashier.cons.repository.TbConsInfoRepository;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.utils.FileUtil;
import cn.ysk.cashier.utils.PageUtil;
import cn.ysk.cashier.utils.QueryHelp;
@ -65,6 +66,12 @@ public class TbConCheckServiceImpl implements TbConCheckService {
@Override
@Transactional(rollbackFor = Exception.class)
public TbConCheckDto create(TbConCheck resources) throws Exception {
if(BigDecimal.ZERO.compareTo(resources.getStockNumber())>0||resources.getStockNumber().compareTo(new BigDecimal("99999999999999"))>0){
throw new BadRequestException("请输入正确的数值");
}
TbConsInfo consInfo= tbConsInfoRepository.getById(resources.getConInfoId());
if(Objects.isNull(consInfo)){
throw new Exception("耗材信息不存在");

View File

@ -0,0 +1,128 @@
package cn.ysk.cashier.controller.product;
import cn.ysk.cashier.annotation.AnonymousAccess;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.dto.shoptable.*;
import cn.ysk.cashier.pojo.order.TbCashierCart;
import cn.ysk.cashier.service.product.TbProductService;
import cn.ysk.cashier.service.shop.TbShopTableService;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.Validator;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping("/api/place")
public class TbPlaceController {
private final TbShopTableService tbShopTableService;
private final TbProductService tbProductService;
private final Validator validator;
@AnonymousAccess
@GetMapping ("/activate")
@ApiOperation("查询/product")
public ResponseEntity<Object> queryActivateTbProductInfo(
@RequestParam(defaultValue = "0") Integer page,
@RequestParam(defaultValue = "30") Integer size,
@RequestParam(required = false) Integer categoryId,
@RequestParam Integer shopId,
@RequestParam(required = false) Integer productId
){
return new ResponseEntity<>(tbProductService.activateProduct(page, size, categoryId, shopId, productId),HttpStatus.OK);
}
public TbPlaceController(TbShopTableService tbShopTableService, TbProductService tbProductService, Validator validator) {
this.tbShopTableService = tbShopTableService;
this.tbProductService = tbProductService;
this.validator = validator;
}
@AnonymousAccess
@PostMapping("/addCart")
@Log("代客下单:#addCartDTO.tableId")
@ApiOperation("代客下单/shop/table")
public ResponseEntity<TbCashierCart> addCartForUser(@Valid @RequestBody AddCartDTO addCartDTO) {
return ResponseEntity.ok(tbShopTableService.addCartForUser(addCartDTO));
}
@AnonymousAccess
@PutMapping("/updateCart")
@Log("代客下单")
@ApiOperation("代客下单/shop/table")
public ResponseEntity<TbCashierCart> updateCart(@Valid @RequestBody UpdateCartDTO updateCartDTO) {
return ResponseEntity.ok(tbShopTableService.updateCart(updateCartDTO));
}
@AnonymousAccess
@PutMapping("/pack")
@Log("代客下单")
@ApiOperation("代客下单/shop/table")
public ResponseEntity<TbCashierCart> pack(@Valid @RequestBody PackCartDTO packCartDTO) {
tbShopTableService.pack(packCartDTO);
return ResponseEntity.ok(null);
}
@AnonymousAccess
@DeleteMapping("/removeCart")
@Log("代客下单 删除购物车商品")
@ApiOperation("代客下单 清空购物车 /shop/table")
public ResponseEntity<Object> removeCart(@Validated @RequestBody RemoveCartDTO removeCartDTO) {
tbShopTableService.removeCart(removeCartDTO);
return new ResponseEntity<>(HttpStatus.OK);
}
@AnonymousAccess
@DeleteMapping("/clearCart")
@Log("代客下单 清空购物车")
@ApiOperation("代客下单 清空购物车 /shop/table"/**/)
public ResponseEntity<Object> clearCart(@Validated @RequestBody ClearCartDTO clearCartDTO) {
tbShopTableService.clearCart(clearCartDTO);
return new ResponseEntity<>(HttpStatus.OK);
}
@AnonymousAccess
@GetMapping("/cart")
@Log("代客下单 查询购物车")
@ApiOperation("代客下单 查询购物车 /shop/table")
public ResponseEntity<Object> getCart(
@RequestParam Long tableId,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam Integer shopId,
@RequestParam(required = false) Integer vipUserId
) {
return ResponseEntity.ok(tbShopTableService.getCart(tableId, page, size, shopId, vipUserId));
}
@AnonymousAccess
@GetMapping("/masterId")
@Log("代客下单 查询购物车")
@ApiOperation("代客下单 ")
public ResponseEntity<Object> getMasterId(
@RequestParam Integer shopId,
@RequestParam Long tableId,
@RequestParam(required = false) Integer vipUserId
) {
return ResponseEntity.ok(tbShopTableService.getMasterId(shopId, tableId, vipUserId));
}
@AnonymousAccess
@PostMapping("/order")
@Log("代客下单 查询购物车")
@ApiOperation("代客下单 查询购物车 /shop/table")
public ResponseEntity<Object> createOrder(
@RequestBody CreateOrderDTO createOrderDTO
) {
return ResponseEntity.ok(tbShopTableService.createOrder(createOrderDTO));
}
}

View File

@ -1,5 +1,6 @@
package cn.ysk.cashier.controller.product;
import cn.ysk.cashier.annotation.AnonymousAccess;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.dto.product.TbProductSortCriteria;
import cn.ysk.cashier.vo.TbProductVo;
@ -32,6 +33,8 @@ public class TbProductController {
return new ResponseEntity<>(tbProductService.queryAll(criteria, false),HttpStatus.OK);
}
@GetMapping("/list")
@ApiOperation("查询/productForAdmin")
public ResponseEntity<Object> queryTbProductForAdmin(TbProductQueryCriteria criteria){
@ -49,12 +52,15 @@ public class TbProductController {
public Object queryTbProductInfo(@PathVariable("product") Integer product)throws Exception{
return tbProductService.findByProductId(product);
}
@GetMapping ("/productList")
@ApiOperation("查询/product")
public Object queryTbProductInfo(@RequestParam List<String> productList){
return tbProductService.findByProductList(productList);
}
@PostMapping("/upProSort")
@ApiOperation("修改商品排序")
public ResponseEntity<Object> upProSort(@RequestBody TbProductSortCriteria param){

View File

@ -0,0 +1,78 @@
package cn.ysk.cashier.controller.shop;
import cn.ysk.cashier.annotation.AnonymousAccess;
import cn.ysk.cashier.dto.shop.*;
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
import cn.ysk.cashier.pojo.shop.TbFullShopId;
import cn.ysk.cashier.service.shop.MsgService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
@RestController
@RequestMapping("/api/msg")
public class MsgController {
private final MsgService msgService;
public MsgController(MsgService msgService) {
this.msgService = msgService;
}
/**
* 获取所有订阅消息用户
* @return
*/
@AnonymousAccess
@GetMapping("/all")
public ResponseEntity<Page<TbFullShopId>> all(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam Integer shopId,
@RequestParam(required = false) String nickName,
@RequestParam(required = false) String openId,
@RequestParam(required = false) Integer state,
@RequestParam(required = false) Integer type
) {
Page<TbFullShopId> all = msgService.all(page, size, shopId, nickName, openId, state, type);
return ResponseEntity.ok(all);
}
@AnonymousAccess
@PutMapping("/shopState")
public ResponseEntity<Boolean> shopMsgState(
@Valid @RequestBody ShopMsgStateDTO shopMsgStateDTO
) {
return ResponseEntity.of(msgService.updateShopState(shopMsgStateDTO));
}
@AnonymousAccess
@DeleteMapping
public ResponseEntity<Boolean> removeSubUser(
@Valid @RequestBody ShopMsgRemoveDTO shopMsgRemoveDTO
) {
return ResponseEntity.of(msgService.removeSubUser(shopMsgRemoveDTO));
}
@AnonymousAccess
@PutMapping("/info")
public ResponseEntity<Boolean> updateInfo(
@Valid @RequestBody ShopInfoUpdateDTO shopInfoUpdateDTO
) {
return ResponseEntity.of(msgService.updateInfo(shopInfoUpdateDTO));
}
@AnonymousAccess
@GetMapping("/state")
public ResponseEntity<HashMap<String, Object>> updateInfo(
@RequestParam Integer shopId
) {
return ResponseEntity.ok(msgService.getInfo(shopId, null));
}
}

View File

@ -16,10 +16,12 @@
package cn.ysk.cashier.controller.shop;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.dto.shoptable.AddCartDTO;
import cn.ysk.cashier.dto.shoptable.ClearCartDTO;
import cn.ysk.cashier.dto.shoptable.RemoveCartDTO;
import cn.ysk.cashier.pojo.shop.TbShopTable;
import cn.ysk.cashier.service.shop.TbShopTableService;
import cn.ysk.cashier.dto.shop.TbShopTableQueryCriteria;
import org.springframework.data.domain.Pageable;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@ -84,4 +86,7 @@ public class TbShopTableController {
tbShopTableService.deleteAll(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
}
}

View File

@ -0,0 +1,22 @@
package cn.ysk.cashier.dto.shop;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class ShopInfoUpdateDTO {
@NotNull
private Integer shopId;
@NotNull
private String openId;
private String note;
@Range(min = 0, max = 1)
private Integer state;
private Integer type;
private String nickName;
private String avatar;
}

View File

@ -0,0 +1,14 @@
package cn.ysk.cashier.dto.shop;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class ShopMsgRemoveDTO {
@NotNull
private Integer shopId;
@NotBlank
private String openId;
}

View File

@ -0,0 +1,15 @@
package cn.ysk.cashier.dto.shop;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotNull;
@Data
public class ShopMsgStateDTO {
@NotNull
private Integer shopId;
@Range(min = 0, max = 1)
private Integer state;
private Integer type;
}

View File

@ -0,0 +1,13 @@
package cn.ysk.cashier.dto.shop;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class ShopTypeDTO {
@NotNull
private Integer shopId;
@NotNull
private Integer type;
}

View File

@ -0,0 +1,15 @@
package cn.ysk.cashier.dto.shop;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class ShopUserMsgState {
@NotNull
private Integer state;
@NotNull
private Integer shopId;
@NotNull
private Integer id;
}

View File

@ -0,0 +1,27 @@
package cn.ysk.cashier.dto.shoptable;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
public class AddCartDTO {
@NotEmpty
private String masterId;
private Integer vipUserId;
@NotNull
private Integer productId;
@NotNull
private Integer skuId;
@NotNull
private Integer shopId;
@NotEmpty
private String tableId;
@NotNull
@Min(0)
private Integer num;
private boolean isPack;
private boolean isGift;
}

View File

@ -0,0 +1,17 @@
package cn.ysk.cashier.dto.shoptable;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
public class ClearCartDTO {
@NotEmpty
private String masterId;
private Integer vipUserId;
@NotNull
private Long tableId;
@NotNull
private String shopId;
}

View File

@ -0,0 +1,18 @@
package cn.ysk.cashier.dto.shoptable;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
public class CreateOrderDTO {
@NotEmpty
private String masterId;
private Integer vipUserId;
@NotNull
private Integer shopId;
@NotEmpty
private String tableId;
private String note;
}

View File

@ -0,0 +1,21 @@
package cn.ysk.cashier.dto.shoptable;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
public class PackCartDTO {
@NotEmpty
private String masterId;
private Integer vipUserId;
@NotNull
private Integer shopId;
@NotEmpty
private String tableId;
@NotNull
@Range(min = 0, max = 1)
private Integer state;
}

View File

@ -0,0 +1,16 @@
package cn.ysk.cashier.dto.shoptable;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
public class RemoveCartDTO {
@NotNull
private Integer cartId;
@NotNull
private Integer shopId;
@NotNull
private Long tableId;
}

View File

@ -0,0 +1,23 @@
package cn.ysk.cashier.dto.shoptable;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data
public class UpdateCartDTO {
@NotNull
private Integer cartId;
@NotNull
private Integer skuId;
@NotNull
private Integer productId;
@NotNull
private Integer shopId;
@NotNull
@Min(0)
private Integer num;
}

View File

@ -0,0 +1,17 @@
package cn.ysk.cashier.enums;
public enum ShopWxMsgTypeEnum {
ALL_MSG(-1),
STOCK_MSG(0),
CONSUMABLES_MSG(1),
OPERATION_MSG(2);
private final Integer type;
ShopWxMsgTypeEnum(Integer type) {
this.type = type;
}
public Integer getType() {
return type;
}
}

View File

@ -0,0 +1,34 @@
package cn.ysk.cashier.mybatis.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.time.Instant;
@Getter
@Setter
@Entity
@Table(name = "tb_shop_msg_state")
public class TbShopMsgState {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "shop_id")
private Integer shopId;
@Column(name = "type")
private Integer type;
@Column(name = "state")
private Integer state;
@Column(name = "create_time")
private Instant createTime;
@Column(name = "update_time")
private Instant updateTime;
}

View File

@ -1,59 +1,51 @@
package cn.ysk.cashier.mybatis.entity;
import java.io.Serializable;
import java.time.LocalDateTime;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* 商家openid信息表
* @TableName tb_shop_open_id
*/
@Table(name="tb_shop_open_id")
@Data
@EqualsAndHashCode
public class TbShopOpenId implements Serializable {
/**
*
*/
import javax.persistence.*;
import javax.validation.constraints.Size;
import java.time.Instant;
@Getter
@Setter
@Entity
@Table(name = "tb_shop_open_id")
public class TbShopOpenId {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Integer id;
/**
* 店铺id
*/
@Column(name = "shop_id")
private Integer shopId;
/**
* 已经订阅消息的商家微信号
*/
@Size(max = 5000)
@Column(name = "open_id", length = 5000)
private String openId;
/**
*
*/
@Column(name = "status")
private Integer status;
/**
*
*/
private LocalDateTime createTime;
@Column(name = "create_time")
private Instant createTime;
/**
*
*/
private LocalDateTime updateTime;
@Column(name = "update_time")
private Instant updateTime;
/**
* 类型 -1 任意消息 0库存预警
*/
@Column(name = "type")
private Integer type;
private static final long serialVersionUID = 1L;
@Size(max = 255)
@Column(name = "nickname")
private String nickname;
@Size(max = 255)
@Column(name = "avatar")
private String avatar;
@Size(max = 255)
@Column(name = "note")
private String note;
}

View File

@ -0,0 +1,10 @@
package cn.ysk.cashier.mybatis.mapper;
import cn.ysk.cashier.mybatis.entity.Activate;
import cn.ysk.cashier.pojo.order.TbCashierCart;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface TbCashierCartMapper extends BaseMapper<TbCashierCart> {
}

View File

@ -0,0 +1,7 @@
package cn.ysk.cashier.mybatis.mapper;
import cn.ysk.cashier.pojo.order.TbOrderDetail;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface TbOrderDetailMapper extends BaseMapper<TbOrderDetail> {
}

View File

@ -0,0 +1,37 @@
package cn.ysk.cashier.mybatis.mapper;
import cn.ysk.cashier.mybatis.entity.TbMShopUser;
import cn.ysk.cashier.pojo.order.TbOrderInfo;
import cn.ysk.cashier.vo.TbOrderSaleVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
public interface TbOrderInfoMapper extends BaseMapper<TbOrderInfo> {
@Select("<script>" +
" SELECT \n" +
" oi.order_no, \n" +
" od.num, \n" +
" od.price, \n" +
" od.status, od.product_sku_id skuId \n" +
" FROM \n" +
" tb_order_info oi \n" +
" LEFT JOIN \n" +
" tb_order_detail od ON oi.id = od.order_id \n" +
" WHERE \n" +
" od.shop_id = #{shopId} \n" +
" AND (od.status = 'closed' OR od.status = 'refund') \n" +
" AND od.create_time > #{startTime} \n" +
" AND od.create_time &lt; #{endTime} \n" +
" AND (od.product_sku_id IN \n" +
" <foreach item=\"productSkuId\" collection=\"productSkuIds\" open=\"(\" separator=\",\" close=\")\"> \n" +
" #{productSkuId} \n" +
" </foreach> \n" +
" ) " +
"</script>")
List<TbOrderSaleVO> selectAllSaleInfo(@Param("startTime") Timestamp startTime, @Param("endTime") Timestamp endTime, @Param("productSkuIds") List<Integer> productSkuIds, @Param("shopId") Integer shopId);
}

View File

@ -2,10 +2,14 @@ package cn.ysk.cashier.mybatis.mapper;
import cn.ysk.cashier.pojo.product.TbProductSku;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
public interface TbProducSkutMapper extends BaseMapper<TbProductSku> {
@ -14,4 +18,13 @@ public interface TbProducSkutMapper extends BaseMapper<TbProductSku> {
@Update("update tb_product_sku set stock_number=#{stocktakinNum} where id=#{id} and stock_number=#{stockNumber}")
Integer updateStock(@Param("id") Integer id,@Param("stockNumber") Double stockNumber,@Param("stocktakinNum") Integer stocktakinNum);
@Update("update tb_product_sku set stock_number=stock_number+#{addNum} WHERE id=#{skuId}")
int incrStock(@Param("skuId") Integer skuId, @Param("addNum") Integer addNum);
@Update("update tb_product_sku set stock_number=stock_number-#{num} WHERE id=#{id} and stock_number-#{num} >= 0")
int decrStock(String id, int num);
@Update("update tb_product_sku set stock_number=stock_number-#{num} WHERE id=#{id} ")
int decrStockUnCheck(String id, int num);
}

View File

@ -1,9 +1,27 @@
package cn.ysk.cashier.mybatis.mapper;
import cn.ysk.cashier.pojo.product.TbProduct;
import cn.ysk.cashier.pojo.product.TbProductSku;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.data.jpa.repository.Query;
public interface TbProductMapper extends BaseMapper<TbProduct> {
@Select("select * from tb_product_sku as sku where sku.is_del=0 and sku.is_grounding=1 and sku.is_pause_sale=0 and sku.shop_id=#{shopId} and sku.id=#{skuId}")
TbProductSku selectSkuByIdAndShopId(@Param("shopId") Integer shopId, @Param("skuId") Integer skuId);
}
@Select("select * from tb_product product where product.id=#{id} and product.shop_id=#{shopId} and product.is_del=0")
TbProduct selectByIdAndShopId(@Param("shopId") Integer shopId, @Param("id") Integer id);
@Update("update tb_product set stock_number=stock_number+#{addNum} WHERE id=#{id}")
int incrStock(@Param("id") Integer id, @Param("addNum") Integer addNum);
@Update("update tb_product set stock_number=stock_number-#{decrNum} WHERE id=#{productId} and stock_number-#{decrNum} >= 0")
int decrStock(@Param("productId") Integer productId, @Param("decrNum") int decrNum);
@Update("update tb_product set stock_number=stock_number-#{num} WHERE id=#{id}")
int decrStockUnCheck(Integer id, int num);
}

View File

@ -0,0 +1,18 @@
package cn.ysk.cashier.mybatis.mapper;
import cn.ysk.cashier.mybatis.entity.TbShopMsgState;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author Administrator
* @description 针对表tb_shop_msg_state的数据库操作Mapper
* @createDate 2024-08-12 13:39:46
* @Entity cn.ysk.cashier.mybatis.pojo.TbShopMsgStatetb
*/
public interface TbShopMsgStateMapper extends BaseMapper<TbShopMsgState> {
}

View File

@ -1,16 +1,48 @@
package cn.ysk.cashier.mybatis.mapper;
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
import cn.ysk.cashier.pojo.shop.TbFullShopId;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* @author Administrator
* @description 针对表tb_shop_open_id(商家openid信息表)的数据库操作Mapper
* @createDate 2024-08-02 10:00:27
* @createDate 2024-08-08 11:14:32
* @Entity cn.ysk.cashier.mybatis.entity.TbShopOpenId
*/
public interface TbShopOpenIdMapper extends BaseMapper<TbShopOpenId> {
@Update("update tb_shop_open_id set status=#{state} where shop_id=#{shopId} and status != #{state}")
int updateShopState(@Param("shopId") Integer shopId, @Param("state") Integer state);
@Update("update tb_shop_open_id set status=#{state} and shop_id=#{shopId} and id=#{id}")
int updateStateById(@Param("state") Integer state, @Param("shopId") Integer shopId, @Param("id") Integer id);
@Update("update tb_shop_open_id set type")
int updateTypeByShopId(@Param("shopId") Integer shopId, @Param("type") Integer type);
@Select("<script>" +
" select *,\n" +
" SUM(IF(type = 0, `status`, 0)) AS proState,\n" +
" SUM(IF(type = 1, `status`, 0)) AS conState,\n" +
" SUM(IF(type = 2, `status`, 0)) AS opeState,\n" +
" SUM(IF(type = -1, `status`, 0)) AS allState\n" +
" from tb_shop_open_id where shop_id=#{shopId}\n" +
" <if test=\"nickName !=null and nickName != ''\">\n" +
" and nickname like concat('%', #{nickName} '%')\n" +
" </if>\n" +
" <if test=\"openId !=null and openId != ''\">\n" +
" and open_id like concat('%', #{openId} '%')\n" +
" </if>\n" +
" group by shop_id, open_id" +
"</script>")
Page<TbFullShopId> selectAll(@Param("shopId") Integer shopId, @Param("nickName") String nickName, @Param("openId") String openId, Page<TbFullShopId> page);
}

View File

@ -1,18 +1,33 @@
package cn.ysk.cashier.mybatis.rest;
import cn.hutool.core.io.IoUtil;
import cn.hutool.http.HttpUtil;
import cn.ysk.cashier.annotation.rest.AnonymousPostMapping;
import cn.ysk.cashier.domain.QiniuContent;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mybatis.entity.Activate;
import cn.ysk.cashier.mybatis.service.ShopService;
import cn.ysk.cashier.service.QiNiuService;
import cn.ysk.cashier.utils.CacheKey;
import cn.ysk.cashier.utils.RedisUtils;
import cn.ysk.cashier.utils.SecurityUtils;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.annotation.Log;
import cn.ysk.cashier.mybatis.entity.StorageVo;
import cn.ysk.cashier.mybatis.service.ShopService;
import cn.ysk.cashier.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j
@RestController
@RequiredArgsConstructor
@Api(tags = "/shop/storage")
@ -20,6 +35,13 @@ import org.springframework.web.bind.annotation.*;
public class StorageController {
@Autowired
private ShopService shopService;
private final RedisUtils redisUtils;
private final QiNiuService qiNiuService;
private static final String APP_ID = "wxd88fffa983758a30";
private static final String APP_SECRET = "a34a61adc0602118b49400baa8812454";
private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
private static final String QR_CODE_URL = "https://api.weixin.qq.com/wxa/getwxacode";
@GetMapping("/findActivate")
public ResponseEntity<Object> findActivate(@RequestParam String shopId){
@ -32,4 +54,47 @@ public class StorageController {
shopService.modityActivate(activate);
return new ResponseEntity<>(HttpStatus.OK);
}
/**
* @param params
* shopId 必填
* env_version 存在即生成体验版
* @return
*/
@PostMapping("/getwxacode")
public ResponseEntity<Object> getwxacode(@RequestBody Map<String, Object> params) {
if (CollectionUtils.isEmpty(params) || !params.containsKey("shopId")) throw new BadRequestException("参数错误");
if (redisUtils.hasKey(CacheKey.VIPCODE + params.get("shopId"))) return new ResponseEntity<>(redisUtils.get(CacheKey.VIPCODE + params.get("shopId")),HttpStatus.OK);
try {
InputStream qrCodeStream = fetchQRCode(params);
QiniuContent qiniuContent = qiNiuService.uploadByte(IoUtil.readBytes(qrCodeStream),qiNiuService.findCloud());
redisUtils.set(CacheKey.VIPCODE + params.get("shopId"),qiniuContent.getUrl());
return new ResponseEntity<>(qiniuContent.getUrl(),HttpStatus.OK);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Failed to generate QR code: " + e.getMessage());
}
}
private String getAccessToken() {
String url = String.format("%s?grant_type=client_credential&appid=%s&secret=%s", TOKEN_URL, APP_ID, APP_SECRET);
String response = HttpUtil.get(url);
JSONObject jsonResponse = JSONObject.parseObject(response);
if (!jsonResponse.containsKey("access_token")) {
throw new RuntimeException("Failed to retrieve access token: " + response);
}
return jsonResponse.getString("access_token");
}
private InputStream fetchQRCode(Map<String, Object> params) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("path", "pages/member/index");//路径
jsonObject.addProperty("is_hyaline", true);//是否需要透明底色 true 生成透明底色的小程序码
if (params.containsKey("env_version")) jsonObject.addProperty("env_version", "trial");//正式版为 release体验版为 trial开发版为 develop
String accessToken = getAccessToken();
String url = String.format("%s?access_token=%s&shopId=%s", QR_CODE_URL, accessToken,params.get("shopId"));
return HttpUtil.createPost(url)
.body(jsonObject.toString(), "application/json")
.execute()
.bodyStream();
}
}

View File

@ -0,0 +1,13 @@
package cn.ysk.cashier.mybatis.service;
import cn.ysk.cashier.mybatis.entity.TbShopMsgState;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description 针对表tb_shop_msg_state的数据库操作Service
* @createDate 2024-08-12 13:39:46
*/
public interface TbShopMsgStateService extends IService<TbShopMsgState> {
}

View File

@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author Administrator
* @description 针对表tb_shop_open_id(商家openid信息表)的数据库操作Service
* @createDate 2024-08-02 10:00:27
* @createDate 2024-08-08 11:14:32
*/
public interface TbShopOpenIdService extends IService<TbShopOpenId> {

View File

@ -0,0 +1,22 @@
package cn.ysk.cashier.mybatis.service.impl;
import cn.ysk.cashier.mybatis.entity.TbShopMsgState;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.ysk.cashier.mybatis.service.TbShopMsgStateService;
import cn.ysk.cashier.mybatis.mapper.TbShopMsgStateMapper;
import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description 针对表tb_shop_msg_state的数据库操作Service实现
* @createDate 2024-08-12 13:39:46
*/
@Service
public class TbShopMsgStateServiceImpl extends ServiceImpl<TbShopMsgStateMapper, TbShopMsgState>
implements TbShopMsgStateService{
}

View File

@ -9,7 +9,7 @@ import org.springframework.stereotype.Service;
/**
* @author Administrator
* @description 针对表tb_shop_open_id(商家openid信息表)的数据库操作Service实现
* @createDate 2024-08-02 10:00:27
* @createDate 2024-08-08 11:14:32
*/
@Service
public class TbShopOpenIdServiceImpl extends ServiceImpl<TbShopOpenIdMapper, TbShopOpenId>

View File

@ -220,6 +220,9 @@ public class TbOrderInfo implements Serializable {
@ApiModelProperty(value = "是否购买优惠券")
private String isBuyCoupon;
@Column(name = "`out_number`")
private String outNumber;
@Column(name = "`is_use_coupon`")
@ApiModelProperty(value = "是否使用优惠券")
private String isUseCoupon;

View File

@ -0,0 +1,328 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.pojo.product;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.annotations.ApiModelProperty;
import cn.hutool.core.bean.copier.CopyOptions;
import lombok.EqualsAndHashCode;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.io.Serializable;
/**
* @website https://eladmin.vip
* @description /
* @author lyf
* @date 2023-12-11
**/
@Entity
@Data
@Table(name="tb_product")
@TableName("tb_product")
public class TbProductAndSku implements Serializable {
@Id
@Column(name = "`id`")
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "id")
@TableId(type = IdType.AUTO)
private Integer id;
@Column(name = "`source_path`")
@ApiModelProperty(value = "商品来源 NORMAL普通商品 --,SCORE积分商品")
private String sourcePath="NORMAL";
@Column(name = "`merchant_id`")
@ApiModelProperty(value = "商户Id")
private String merchantId = "PLANT_ID";
@Column(name = "`shop_id`")
@ApiModelProperty(value = "店铺id")
private String shopId;
@Column(name = "`name`")
@ApiModelProperty(value = "商品名称")
private String name;
@Column(name = "`type`")
@ApiModelProperty(value = "商品类型(属性):REAL- 实物商品 VIR---虚拟商品")
private String type = "REAL";
@Column(name = "`pack_fee`")
@ApiModelProperty(value = "包装费")
private BigDecimal packFee;
@Column(name = "`low_price`",nullable = false)
@NotNull
@ApiModelProperty(value = "商品最低价")
private BigDecimal lowPrice;
@Column(name = "`unit_id`")
@ApiModelProperty(value = "单位Id")
private Integer unitId;
@Column(name = "`cover_img`")
@ApiModelProperty(value = "商品封面图")
private String coverImg;
@Column(name = "`category_id`")
@ApiModelProperty(value = "categoryId")
private String categoryId;
@Column(name = "`spec_id`")
@ApiModelProperty(value = "商品规格")
private Integer specId;
@Column(name = "`brand_id`")
@ApiModelProperty(value = "品牌Id")
private Integer brandId;
@Column(name = "`short_title`")
@ApiModelProperty(value = "短标题--促销语")
private String shortTitle;
@Column(name = "`low_member_price`")
@ApiModelProperty(value = "lowMemberPrice")
private BigDecimal lowMemberPrice;
@Column(name = "`unit_snap`")
@ApiModelProperty(value = "单位镜像")
private String unitSnap;
@Column(name = "`share_img`")
@ApiModelProperty(value = "商品分享图")
private String shareImg;
@Column(name = "`images`")
@ApiModelProperty(value = "商品图片(第一张为缩略图,其他为详情)")
private String images;
@Column(name = "`video`")
@ApiModelProperty(value = "商品视频URL地址")
private String video;
@Column(name = "`video_cover_img`")
@ApiModelProperty(value = "视频封面图")
private String videoCoverImg;
@Column(name = "`sort`")
@ApiModelProperty(value = "排序")
private Integer sort = 0;
@Column(name = "`limit_number`")
@ApiModelProperty(value = "0-不限购")
private Integer limitNumber = 0;
@Column(name = "`product_score`")
@ApiModelProperty(value = "商品赚送积分")
private Integer productScore;
@Column(name = "`status`",nullable = false)
@NotNull
@ApiModelProperty(value = "0--待审核 1审核通过 -1审核失败 -2违规下架")
private Integer status = 0;
@Column(name = "`fail_msg`")
@ApiModelProperty(value = "审核失败原因")
private String failMsg;
@Column(name = "`is_recommend`")
@ApiModelProperty(value = "是否推荐,店铺推荐展示")
private Integer isRecommend = 0;
@Column(name = "`is_hot`")
@ApiModelProperty(value = "是否热销")
private Integer isHot = 0;
@Column(name = "`is_new`")
@ApiModelProperty(value = "是否新品")
private Integer isNew;
@Column(name = "`is_on_sale`")
@ApiModelProperty(value = "是否促销1-是0-否")
private Integer isOnSale = 0;
@Column(name = "`is_show`")
@ApiModelProperty(value = "是否展示0-下架 1上架---废弃")
private Integer isShow = 0;
@Column(name = "`type_enum`")
@ApiModelProperty(value = "商品规格0-单规格 1多规格")
private String typeEnum;
@Column(name = "`is_distribute`")
@ApiModelProperty(value = "是否共享库存")
private Integer isDistribute = 0;
@Column(name = "`is_del`",nullable = false)
@NotNull
@ApiModelProperty(value = "是否回收站 0-否1回收站")
private Integer isDel = 0;
@Column(name = "`is_stock`")
@ApiModelProperty(value = "是否开启库存")
private Integer isStock = 1;
@Column(name = "`is_pause_sale`")
@ApiModelProperty(value = "是否暂停销售")
private Integer isPauseSale = 0;
@Column(name = "`is_free_freight`",nullable = false)
@NotNull
@ApiModelProperty(value = "是否免邮1-是 0-否")
private Integer isFreeFreight=1;
@Column(name = "`freight_id`")
@ApiModelProperty(value = "邮费模版")
private Long freightId;
@Column(name = "`strategy_type`")
@ApiModelProperty(value = "商品当前生效策略")
private String strategyType;
@Column(name = "`strategy_id`")
@ApiModelProperty(value = "策略Id")
private Integer strategyId = 1;
@Column(name = "`is_vip`")
@ApiModelProperty(value = "vip专属")
private Integer isVip = 0;
@Column(name = "`is_delete`",nullable = false)
@NotNull
@ApiModelProperty(value = "是否删除")
private Integer isDelete = 0;
@Column(name = "`notice`")
@ApiModelProperty(value = "购买须知")
private String notice;
@Column(name = "`created_at`")
@ApiModelProperty(value = "createdAt")
private Long createdAt;
@Column(name = "`updated_at`")
@ApiModelProperty(value = "updatedAt")
private Long updatedAt;
@Column(name = "`base_sales_number`")
@ApiModelProperty(value = "基础出售数量")
private Double baseSalesNumber =0.00;
@Column(name = "`real_sales_number`")
@ApiModelProperty(value = "实际销量")
private Double realSalesNumber = (double) 0;
@Column(name = "`sales_number`")
@ApiModelProperty(value = "合计销量")
private Integer salesNumber = 0;
@Column(name = "`thumb_count`")
@ApiModelProperty(value = "点赞次数")
private Integer thumbCount = 0;
@Column(name = "`store_count`")
@ApiModelProperty(value = "收藏次数")
private Integer storeCount = 0;
@Column(name = "`furnish_meal`")
@ApiModelProperty(value = "支持堂食")
private Integer furnishMeal = 0;
@Column(name = "`furnish_express`")
@ApiModelProperty(value = "支持配送")
private Integer furnishExpress = 0;
@Column(name = "`furnish_draw`")
@ApiModelProperty(value = "支持自提")
private Integer furnishDraw = 0;
@Column(name = "`furnish_vir`")
@ApiModelProperty(value = "支持虚拟")
private Integer furnishVir = 0;
@Column(name = "`is_combo`")
@ApiModelProperty(value = "是否套餐")
private Integer isCombo =0;
@Column(name = "`group_snap`")
@ApiModelProperty(value = "套餐内容")
private String groupSnap;
@Column(name = "`is_show_cash`")
@ApiModelProperty(value = "isShowCash")
private Integer isShowCash =0;
@Column(name = "`is_show_mall`")
@ApiModelProperty(value = "isShowMall")
private Integer isShowMall = 0;
@Column(name = "`is_need_examine`")
@ApiModelProperty(value = "是否需要审核")
private Integer isNeedExamine = 0;
@Column(name = "`show_on_mall_status`")
@ApiModelProperty(value = "线上商城展示状态0待审核 -1 异常 1正常")
private Integer showOnMallStatus = 1;
@Column(name = "`show_on_mall_time`")
@ApiModelProperty(value = "提交审核时间")
private Long showOnMallTime;
@Column(name = "`show_on_mall_error_msg`")
@ApiModelProperty(value = "线上商城展示失败原因")
private String showOnMallErrorMsg;
@Column(name = "`enable_label`")
@ApiModelProperty(value = "使用标签打印 选择 是 并在 前台>本机设置 勾选打印标签后,收银完成后会自动打印对应数量的标签数")
private Integer enableLabel = 0;
@Column(name = "`tax_config_id`")
@ApiModelProperty(value = "税率")
private String taxConfigId;
@Column(name = "spec_info")
@ApiModelProperty(value = "specInfo")
private String specInfo;
@Column(name = "select_spec")
@ApiModelProperty(value = "selectSpec")
private String selectSpec;
@Column(name = "spec_table_headers")
@ApiModelProperty(value = "specTableHeaders")
private String specTableHeaders;
@Column(name = "group_category_id")
@ApiModelProperty(value = "团购卷分类Id")
private String groupCategoryId;
@Column(name = "stock_number")
@ApiModelProperty("库存数量")
private Double stockNumber = (double) 0;
public void copy(TbProduct source){
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
}
}

View File

@ -0,0 +1,14 @@
package cn.ysk.cashier.pojo.shop;
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class TbFullShopId extends TbShopOpenId {
private Integer proState;
private Integer conState;
private Integer opeState;
private Integer allState;
}

View File

@ -6,6 +6,10 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* @website https://eladmin.vip
@ -18,4 +22,10 @@ public interface TbCashierCartRepository extends JpaRepository<TbCashierCart, In
@Modifying
void updateToFinal(@Param("id") Integer id);
}
@Query("delete from TbCashierCart cart where cart.shopId=:shopId and cart.id=:cartId and cart.tableId=:tableId and cart.status='create'")
@Modifying
@Transactional
void deleteByIdAndShopId(@NotNull String shopId, @NotNull Integer cartId, Long tableId);
}

View File

@ -37,6 +37,19 @@ public interface TbOrderDetailRepository extends JpaRepository<TbOrderDetail, In
@Query("SELECT cart FROM TbOrderDetail cart WHERE cart.orderId in :ids")
List<TbOrderDetail> searchDetailByOrderIds(@Param("ids")List<Integer> ids);
@Query(value = "SELECT " +
"new cn.ysk.cashier.vo.TbOrderSaleVO(oi.orderNo, od.num, od.price, od.status, 0)\n" +
"FROM\n" +
"TbOrderInfo oi\n" +
"LEFT JOIN TbOrderDetail od ON oi.id = od.orderId \n" +
"WHERE\n" +
"od.shopId = :shopId \n" +
"AND ( od.status = 'closed' OR od.status = 'refund' ) \n" +
"AND od.createTime > :startTime \n" +
"AND od.createTime < :endTime \n" +
"AND (:productId is null or od.productId = :productId)\n" +
"AND (:productId is null or od.productSkuId = :productSkuId)")
List<TbOrderSaleVO> querySaleOrderInfo(@Param("startTime") Timestamp startTime, @Param("endTime") Timestamp endTime, @Param("productId") Integer productId, @Param("productSkuId") Integer productSkuId, @Param("shopId") Integer shopId);
@Query("SELECT new cn.ysk.cashier.vo.TbOrderSalesCountByDayVo(" +
@ -102,20 +115,6 @@ public interface TbOrderDetailRepository extends JpaRepository<TbOrderDetail, In
"ORDER BY salesNum DESC")
List<TbOrderSalesCountByDayVo> queryTbOrderSalesCountByDay(@Param("shopId") Integer shopId,@Param("cateId")String cateId,@Param("proName")String proName, @Param("startTime") Date startTime, @Param("endTime") Date endTime);
@Query(value = "SELECT " +
"new cn.ysk.cashier.vo.TbOrderSaleVO(oi.orderNo, od.num, od.price, od.status)\n" +
"FROM\n" +
"TbOrderInfo oi\n" +
"LEFT JOIN TbOrderDetail od ON oi.id = od.orderId \n" +
"WHERE\n" +
"od.shopId = :shopId \n" +
"AND ( od.status = 'closed' OR od.status = 'refund' ) \n" +
"AND od.createTime > :startTime \n" +
"AND od.createTime < :endTime \n" +
"AND (:productId is null or od.productId = :productId)\n" +
"AND (:productSkuId is null or od.productSkuId = :productSkuId)")
List<TbOrderSaleVO> querySaleOrderInfo(@Param("startTime") Timestamp startTime, @Param("endTime") Timestamp endTime, @Param("productId") Integer productId, @Param("productSkuId") Integer productSkuId, @Param("shopId") Integer shopId);
@Query("SELECT new cn.ysk.cashier.vo.TbOrderSalesCountByDayVo(" +
"COALESCE(CAST(SUM(CASE WHEN orders.orderType!='return' THEN info.num ELSE 0 END) as long),0), " +
"COALESCE(CAST(SUM(CASE WHEN orders.orderType='return' THEN info.num ELSE 0 END) as long),0))" +

View File

@ -4,7 +4,9 @@ import cn.ysk.cashier.pojo.shop.TbShopTable;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@ -26,4 +28,9 @@ public interface TbShopTableRepository extends JpaRepository<TbShopTable, Intege
@Query("select table from TbShopTable table where table.shopId = :shopId")
List<TbShopTable> findByShopId(@Param("shopId") Integer shopId);
@Query("delete from TbCashierCart cart where cart.tableId=:tableId and cart.shopId=:shopId and cart.status='create'")
@Modifying
@Transactional
void deleteByTableIdAndShopId(Long tableId, String shopId);
}

View File

@ -4,6 +4,7 @@ import cn.ysk.cashier.dto.ShopSummaryDto;
import cn.ysk.cashier.dto.shop.ShopTableSeleInfoDto;
import cn.ysk.cashier.enums.PayTypeEnum;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mybatis.mapper.TbOrderInfoMapper;
import cn.ysk.cashier.mybatis.service.TbShopUserFlowService;
import cn.ysk.cashier.pojo.shop.TbShopTable;
import cn.ysk.cashier.repository.ShopUserDutyDetailRepository;
@ -39,6 +40,7 @@ import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -68,6 +70,7 @@ public class SummaryServiceImpl implements SummaryService {
@Resource
TbShopAreaRepository tbShopAreaRepository;
private final TbOrderInfoMapper orderInfoMapper;
@Override
@ -407,13 +410,12 @@ public class SummaryServiceImpl implements SummaryService {
@Override
public void download(ShopSummaryDto summaryDto, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
// ConcurrentLinkedQueue<Map<String, Object>> list = new ConcurrentLinkedQueue();
// List<Map<String, Object>> list = new ArrayList<>();
ConcurrentLinkedQueue<Map<String, Object>> list = new ConcurrentLinkedQueue();
if(StringUtils.isBlank(summaryDto.getCateId())){
summaryDto.setCateId(null);
}
ArrayList<Integer> mergeRowIndex = new ArrayList<>();
List<Integer> mergeRowIndex = Collections.synchronizedList(new ArrayList<>());
if (summaryDto.getType() != null && summaryDto.getType() == 1) {//金额
Long start = 1704038400000L;
Long end = Instant.now().toEpochMilli();
@ -439,9 +441,38 @@ public class SummaryServiceImpl implements SummaryService {
}
List<TbOrderSalesCountByDayVo> tbOrderSalesCountByDayVos = detailRepository
.queryTbOrderSalesCountByDay(Integer.valueOf(summaryDto.getShopId()),summaryDto.getCateId(),summaryDto.getProName(), summaryDto.getStartTime(), summaryDto.getEndTime());
ArrayList<Integer> skuIds = new ArrayList<>();
for (TbOrderSalesCountByDayVo tbOrderSalesCountByDayVo : tbOrderSalesCountByDayVos) {
if (tbOrderSalesCountByDayVo.getProductSkuId() != null) {
skuIds.add(tbOrderSalesCountByDayVo.getProductSkuId());
}
}
HashMap<String, List<TbOrderSaleVO>> saleOrderMap = new HashMap<>();
if (!skuIds.isEmpty()) {
List<TbOrderSaleVO> tbOrderSaleVOS = orderInfoMapper.selectAllSaleInfo(new Timestamp(summaryDto.getStartTime().getTime()),
new Timestamp(summaryDto.getEndTime().getTime()), skuIds, Integer.valueOf(summaryDto.getShopId()));
for (TbOrderSaleVO tbOrderSaleVO : tbOrderSaleVOS) {
List<TbOrderSaleVO> orderSaleVOS = saleOrderMap.get(tbOrderSaleVO.getSkuId().toString());
if (orderSaleVOS == null) {
orderSaleVOS = new ArrayList<>();
}
orderSaleVOS.add(tbOrderSaleVO);
saleOrderMap.put(tbOrderSaleVO.getSkuId().toString(), orderSaleVOS);
}
}
tbOrderSalesCountByDayVos.forEach(all -> {
List<TbOrderSaleVO> tbOrderSaleVOS = detailRepository.querySaleOrderInfo(new Timestamp(summaryDto.getStartTime().getTime()),
new Timestamp(summaryDto.getEndTime().getTime()), all.getProductId(), all.getProductSkuId(), Integer.valueOf(summaryDto.getShopId()));
List<TbOrderSaleVO> tbOrderSaleVOS = saleOrderMap.get(all.getProductSkuId().toString());
if (tbOrderSaleVOS == null) {
return;
}
// List<TbOrderSaleVO> tbOrderSaleVOS = detailRepository.querySaleOrderInfo(new Timestamp(summaryDto.getStartTime().getTime()),
// new Timestamp(summaryDto.getEndTime().getTime()), all.getProductId(), all.getProductSkuId(), Integer.valueOf(summaryDto.getShopId()));
for (TbOrderSaleVO tbOrderSaleVO : tbOrderSaleVOS) {
Map<String, Object> map = new LinkedHashMap<>();
map.put("商品分类", all.getCateName());

View File

@ -352,7 +352,7 @@ public class StockServiceImpl implements StockService {
TbProductSku tbProductSku = tbProductSkuRepository.findById(Integer.valueOf(updateValueVO.getTargetId())).orElse(null);
// 推送微信操作消息
if (product != null && tbProductSku != null) {
wxMsgUtils.aboardOperationMsg(("0".equals(updateValueVO.getUpdateValue()) ? "关闭sku售罄: " : "开启sku售罄: ") + product.getName() + "/"+ tbProductSku.getSpecSnap());
wxMsgUtils.aboardOperationMsg(("0".equals(updateValueVO.getUpdateValue()) ? "关闭售罄: " : "开启售罄: ") + product.getName() + "/"+ tbProductSku.getSpecSnap(), Integer.valueOf(updateValueVO.getShopId()));
}else {
log.warn("推送微信操作消息失败未查询到商品信息skuId: {}", updateValueVO.getTargetId());
}
@ -368,7 +368,7 @@ public class StockServiceImpl implements StockService {
TbProduct product1 = tbProductRepository.selectBySkuId(Integer.valueOf(updateValueVO.getTargetId()));
// 推送微信操作消息
if (product1 != null) {
wxMsgUtils.aboardOperationMsg(("0".equals(updateValueVO.getUpdateValue()) ? "关闭售罄: " : "开启售罄: ") + product1.getName());
wxMsgUtils.aboardOperationMsg(("0".equals(updateValueVO.getUpdateValue()) ? "关闭售罄: " : "开启售罄: ") + product1.getName(), Integer.valueOf(updateValueVO.getShopId()));
}else {
log.warn("推送微信操作消息失败未查询到商品信息skuId: {}", updateValueVO.getTargetId());
}
@ -410,7 +410,7 @@ public class StockServiceImpl implements StockService {
TbProduct product = tbProductRepository.selectByShopIdAndId(Integer.parseInt(tbProductSku.getProductId()), String.valueOf(shopId));
// 推送微信操作消息
wxMsgUtils.aboardOperationMsg((isGrounding ? "上架商品: " : "下架商品: ") + product.getName());
wxMsgUtils.aboardOperationMsg((isGrounding ? "上架商品: " : "下架商品: ") + product.getName(), shopId);
// 共享库存下架所有sku
if (product.getIsDistribute().equals(1)) {
tbProductSkuRepository.updateGroundingByProId(product.getId().toString(), isGrounding ? 1 : 0);

View File

@ -96,18 +96,22 @@ public class TbProductGroupServiceImpl implements TbProductGroupService {
@Override
@Transactional(rollbackFor = Exception.class)
public void update(TbProductGroup resources) {
TbProductGroup tbProductGroup = tbProductGroupRepository.findById(resources.getId()).orElseGet(TbProductGroup::new);
// TbProductGroup byName = tbProductGroupRepository.findByName(resources.getName(), resources.getShopId());
// if (byName != null){
// throw new BadRequestException("名称重复");
// }
// 推送微信操作消息
if (!tbProductGroup.getIsShow().equals(resources.getIsShow())) {
wxMsgUtils.aboardOperationMsg((resources.getIsShow() == 0 ? "关闭分组: " : "开启分组: ") + tbProductGroup.getName(), resources.getShopId());
}
tbProductGroup.setUpdatedAt(Instant.now().toEpochMilli());
ValidationUtil.isNull( tbProductGroup.getId(),"TbProductGroup","id",resources.getId());
tbProductGroup.copy(resources);
tbProductGroupRepository.save(tbProductGroup);
// 推送微信操作消息
wxMsgUtils.aboardOperationMsg((resources.getIsShow() == 0 ? "关闭分组: " : "开启分组: ") + tbProductGroup.getName());
}
@Transactional(rollbackFor = Exception.class)

View File

@ -2,6 +2,7 @@ package cn.ysk.cashier.service.impl.productimpl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.StrUtil;
import cn.ysk.cashier.dto.TbPlatformDictDto;
import cn.ysk.cashier.dto.product.TbProductDto;
import cn.ysk.cashier.dto.product.TbProductQueryCriteria;
@ -11,6 +12,7 @@ import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mapper.product.TbProductMapper;
import cn.ysk.cashier.mapper.product.TbProductSkuMapper;
import cn.ysk.cashier.mybatis.entity.TagProductDepts;
import cn.ysk.cashier.mybatis.mapper.TbProducSkutMapper;
import cn.ysk.cashier.mybatis.service.TagProductDeptsService;
import cn.ysk.cashier.pojo.product.*;
import cn.ysk.cashier.pojo.shop.TbPurchaseNotice;
@ -25,6 +27,9 @@ import cn.ysk.cashier.service.shop.TbCouponCategoryService;
import cn.ysk.cashier.utils.*;
import cn.ysk.cashier.vo.TbProductVo;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -70,6 +75,10 @@ public class TbProductServiceImpl implements TbProductService {
private final TbPlatformDictService tbPlatformDictService;
private final TagProductDeptsService tagProductService;
private final TbPurchaseNoticeRepository noticeRepository;
private final TbProducSkutMapper producSkutMapper;
private final cn.ysk.cashier.mybatis.mapper.TbProductMapper productMapper;
private final TbProductSkuResultRepository productSkuResultRepository;
private final RedisUtils redisUtils;
@ -695,4 +704,111 @@ public class TbProductServiceImpl implements TbProductService {
tbProductSkuRepository.incrStock(productSkuId, Double.valueOf(num));
}
}
@Override
public Object activateProduct(Integer page, Integer size, Integer categoryId, Integer shopId, Integer productId) {
com.baomidou.mybatisplus.extension.plugins.pagination.Page<TbProduct> page1 = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, size);
QueryWrapper<TbProduct> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("is_del", 0)
.eq("shop_id", shopId)
.eq("is_delete", 0)
.eq("status", 1)
.eq("is_pause_sale", 0);
// 查询skuResult
ArrayList<Map<String, Object>> infoList = new ArrayList<>();
if (categoryId != null) {
queryWrapper.eq("category_id", categoryId);
}
if (productId != null) {
queryWrapper.eq("id", productId);
}
com.baomidou.mybatisplus.extension.plugins.pagination.Page<TbProduct> tbProductPage = productMapper.selectPage(page1, queryWrapper);
tbProductPage.getRecords().stream().parallel().forEach(item -> {
TbProductSkuResult skuResult = productSkuResultRepository.findById(item.getId()).orElse(null);
List<TbProductSku> tbProductSkus = producSkutMapper.selectList(new LambdaQueryWrapper<TbProductSku>().eq(TbProductSku::getIsDel, 0)
.eq(TbProductSku::getIsPauseSale, 0)
.eq(TbProductSku::getProductId, item.getId())
.eq(TbProductSku::getIsGrounding, 1)
.select(TbProductSku::getId, TbProductSku::getSpecSnap, TbProductSku::getStockNumber, TbProductSku::getSalePrice, TbProductSku::getSuit));
String tagSnap = null;
if (skuResult != null) {
tagSnap = skuResult.getTagSnap();
}
List<String> result = new ArrayList<>();
if (StrUtil.isNotBlank(tagSnap)) {
JSONArray tagSnaps = JSONObject.parseArray(tagSnap);
List<List<String>> valuesList = new ArrayList<>();
// 提取所有 value 的列表
for (int i = 0; i < tagSnaps.size(); i++) {
JSONObject jsonObject = tagSnaps.getJSONObject(i);
String[] values = jsonObject.getString("value").split(",");
valuesList.add(Arrays.asList(values));
}
// 生成所有可能的排列组合
generateCombinations(valuesList, 0, new ArrayList<>(), result);
}
ArrayList<Map<String, Object>> specList = new ArrayList<>();
tbProductSkus.forEach(item2 -> {
Map<String, Object> itemMap = BeanUtil.beanToMap(item2, false, true);
if (item.getIsDistribute().equals(1)) {
itemMap.put("stockNumber", item.getStockNumber());
}else {
itemMap.put("stockNumber", item2.getStockNumber());
}
specList.add(itemMap);
});
ArrayList<HashMap<String, Object>> otherVal = new ArrayList<>();
for (String res : result) {
boolean found = false;
for (Map<String, Object> spec : specList) {
if (res.equals(spec.get("specSnap").toString())) {
spec.put("isGrounding", true);
found = true;
break;
}
}
if (!found) {
HashMap<String, Object> itemMap = new HashMap<>();
itemMap.put("specSnap", res);
itemMap.put("skuId", null);
itemMap.put("isGrounding", false);
otherVal.add(itemMap);
}
}
specList.addAll(otherVal);
Map<String, Object> map = BeanUtil.beanToMap(item, false, false);
map.put("skuResult", skuResult);
map.put("specList", specList);
infoList.add(map);
});
Map<String, Object> map = BeanUtil.beanToMap(tbProductPage, false, false);
map.put("records", infoList);
return map;
}
private static void generateCombinations(List<List<String>> valuesList, int index, List<String> current, List<String> result) {
if (index == valuesList.size()) {
result.add(String.join(",", current));
return;
}
for (String value : valuesList.get(index)) {
current.add(value);
generateCombinations(valuesList, index + 1, current, result);
current.remove(current.size() - 1); // 回溯
}
}
}

View File

@ -0,0 +1,137 @@
package cn.ysk.cashier.service.impl.shopimpl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.ysk.cashier.dto.shop.ShopInfoUpdateDTO;
import cn.ysk.cashier.dto.shop.ShopMsgRemoveDTO;
import cn.ysk.cashier.dto.shop.ShopMsgStateDTO;
import cn.ysk.cashier.mybatis.entity.TbShopMsgState;
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
import cn.ysk.cashier.mybatis.mapper.TbShopOpenIdMapper;
import cn.ysk.cashier.mybatis.service.TbShopMsgStateService;
import cn.ysk.cashier.pojo.shop.TbFullShopId;
import cn.ysk.cashier.service.shop.MsgService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@Service
public class MsgServiceImpl implements MsgService {
private final TbShopOpenIdMapper shopOpenIdMapper;
private final TbShopMsgStateService shopMsgStateService;
public MsgServiceImpl(TbShopOpenIdMapper shopOpenIdMapper, TbShopMsgStateService shopMsgStateService) {
this.shopOpenIdMapper = shopOpenIdMapper;
this.shopMsgStateService = shopMsgStateService;
}
@Override
public Page<TbFullShopId> all(Integer page, Integer size, Integer shopId, String nickName, String openId, Integer state, Integer type) {
return shopOpenIdMapper.selectAll(shopId, nickName, openId, new Page<>(page, size));
}
@Override
public Optional<Boolean> updateShopState(ShopMsgStateDTO shopMsgStateDTO) {
// TbShopOpenId shopOpenId = new TbShopOpenId();
// shopOpenId.setStatus(shopMsgStateDTO.getState());
// LambdaQueryWrapper<TbShopOpenId> queryWrapper = new LambdaQueryWrapper<TbShopOpenId>().eq(TbShopOpenId::getShopId, shopMsgStateDTO.getShopId());
// if (shopMsgStateDTO.getType() != null) {
// queryWrapper.eq(TbShopOpenId::getType, shopMsgStateDTO.getType());
// }
if (shopMsgStateDTO.getType() == null) {
shopMsgStateDTO.setType(-1);
}
TbShopMsgState msgState = shopMsgStateService.lambdaQuery().eq(TbShopMsgState::getType, shopMsgStateDTO.getType())
.eq(TbShopMsgState::getShopId, shopMsgStateDTO.getShopId()).one();
boolean flag;
if (msgState == null) {
msgState = new TbShopMsgState();
msgState.setShopId(shopMsgStateDTO.getShopId());
msgState.setCreateTime(DateUtil.date().toInstant());
msgState.setState(shopMsgStateDTO.getType());
flag = shopMsgStateService.save(msgState);
}else {
flag = shopMsgStateService.lambdaUpdate().eq(TbShopMsgState::getShopId, shopMsgStateDTO.getShopId())
.eq(TbShopMsgState::getType, shopMsgStateDTO.getType())
.set(TbShopMsgState::getState, shopMsgStateDTO.getState())
.set(TbShopMsgState::getUpdateTime, DateUtil.date().toInstant()).update();
}
return Optional.of(flag);
}
@Override
public Optional<Boolean> removeSubUser(ShopMsgRemoveDTO shopMsgRemoveDTO) {
int delete = shopOpenIdMapper.delete(new LambdaQueryWrapper<TbShopOpenId>().eq(TbShopOpenId::getShopId, shopMsgRemoveDTO.getShopId())
.eq(TbShopOpenId::getOpenId, shopMsgRemoveDTO.getOpenId()));
return Optional.of(delete > 0);
}
@Override
public Optional<Boolean> updateInfo(ShopInfoUpdateDTO shopInfoUpdateDTO) {
TbShopOpenId shopOpenId = new TbShopOpenId();
if (StrUtil.isNotBlank(shopInfoUpdateDTO.getNote())) {
shopOpenId.setNote(shopInfoUpdateDTO.getNote());
}
if (shopInfoUpdateDTO.getState() != null) {
shopOpenId.setStatus(shopInfoUpdateDTO.getState());
}
if (shopInfoUpdateDTO.getType() != null) {
shopOpenId.setType(shopInfoUpdateDTO.getType());
}
if (StrUtil.isNotBlank(shopInfoUpdateDTO.getNickName())) {
shopOpenId.setNickname(shopInfoUpdateDTO.getNickName());
}
if (StrUtil.isNotBlank(shopInfoUpdateDTO.getAvatar())) {
shopOpenId.setAvatar(shopInfoUpdateDTO.getAvatar());
}
if (BeanUtil.isNotEmpty(shopOpenId)) {
shopOpenIdMapper.update(shopOpenId, new LambdaQueryWrapper<TbShopOpenId>()
.eq(TbShopOpenId::getOpenId, shopInfoUpdateDTO.getOpenId())
.eq(TbShopOpenId::getType, shopInfoUpdateDTO.getType())
.eq(TbShopOpenId::getShopId, shopInfoUpdateDTO.getShopId()));
}
return Optional.of( true);
}
private static final HashMap<String, String> MSG_TYPE = new HashMap<>();
static {
MSG_TYPE.put("0", "stockState");
MSG_TYPE.put("1", "conState");
MSG_TYPE.put("2", "opeState");
MSG_TYPE.put("-1", "allState");
}
@Override
public HashMap<String, Object> getInfo(Integer shopId, Integer type) {
List<TbShopMsgState> list = shopMsgStateService.lambdaQuery().eq(TbShopMsgState::getShopId, shopId).list();
HashMap<String, Object> data = new HashMap<>();
MSG_TYPE.forEach((k, v) -> {
TbShopMsgState have = null;
for (TbShopMsgState tbShopMsgState : list) {
if (tbShopMsgState.getType().equals(Integer.valueOf(k))) {
have = tbShopMsgState;
break;
}
}
if (have == null) {
TbShopMsgState msgState = new TbShopMsgState();
msgState.setShopId(shopId);
msgState.setCreateTime(DateUtil.date().toInstant());
msgState.setType(Integer.valueOf(k));
msgState.setState(0);
shopMsgStateService.save(msgState);
}
data.put(v, have != null ? have.getState() : 0);
});
return data;
}
}

View File

@ -1,24 +1,47 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.ysk.cashier.service.impl.shopimpl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.ysk.cashier.config.security.security.TokenProvider;
import cn.ysk.cashier.cons.RedisConstant;
import cn.ysk.cashier.cons.rabbit.RabbitConstants;
import cn.ysk.cashier.dto.shoptable.*;
import cn.ysk.cashier.enums.ShopWxMsgTypeEnum;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
import cn.ysk.cashier.mybatis.mapper.*;
import cn.ysk.cashier.pojo.order.TbCashierCart;
import cn.ysk.cashier.pojo.order.TbOrderDetail;
import cn.ysk.cashier.pojo.order.TbOrderInfo;
import cn.ysk.cashier.pojo.product.TbProduct;
import cn.ysk.cashier.pojo.product.TbProductSku;
import cn.ysk.cashier.pojo.shop.TbMerchantAccount;
import cn.ysk.cashier.pojo.shop.TbShopInfo;
import cn.ysk.cashier.pojo.shop.TbShopTable;
import cn.ysk.cashier.utils.ValidationUtil;
import cn.ysk.cashier.utils.FileUtil;
import cn.ysk.cashier.repository.order.TbCashierCartRepository;
import cn.ysk.cashier.repository.product.TbProductRepository;
import cn.ysk.cashier.repository.product.TbProductSkuRepository;
import cn.ysk.cashier.repository.shop.TbShopInfoRepository;
import cn.ysk.cashier.utils.*;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dianguang.cloud.ossservice.model.DateUtils;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.repository.shop.TbShopTableRepository;
import cn.ysk.cashier.service.shop.TbShopTableService;
@ -26,23 +49,29 @@ import cn.ysk.cashier.dto.shop.TbShopTableDto;
import cn.ysk.cashier.dto.shop.TbShopTableQueryCriteria;
import cn.ysk.cashier.mapper.shop.TbShopTableMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import cn.ysk.cashier.utils.QueryHelp;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.*;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletResponse;
/**
* @website https://eladmin.vip
* @description 服务实现
* @author lyf
* @date 2024-01-18
**/
* @author lyf
* @website https://eladmin.vip
* @description 服务实现
* @date 2024-01-18
**/
@Slf4j
@Service
@RequiredArgsConstructor
@ -50,50 +79,70 @@ public class TbShopTableServiceImpl implements TbShopTableService {
private final TbShopTableRepository tbShopTableRepository;
private final TbShopTableMapper tbShopTableMapper;
private final TbProductRepository productRepository;
private final TbProductSkuRepository productSkuRepository;
private final TbCashierCartRepository cashierCartRepository;
private final TbProductMapper productMapper;
private final TbCashierCartMapper cashierCartMapper;
private final RedisUtils redisUtils;
private final TokenProvider tokenProvider;
private final TbMerchantAccountMapper merchantAccountMapper;
private final TbOrderInfoMapper orderInfoMapper;
private final TbOrderDetailMapper orderDetailMapper;
private final TbProducSkutMapper producSkutMapper;
private final RabbitTemplate rabbitTemplate;
private final TbShopInfoRepository shopInfoRepository;
private final TbShopOpenIdMapper shopOpenIdMapper;
private final WxAccountUtil wxAccountUtil;
private final WxMsgUtils wxMsgUtils;
/**
*桌码前缀
* 桌码前缀
*/
private final String QRCODE = "https://kysh.sxczgkj.cn/codeplate?code=";
@Override
public Map<String,Object> queryAll(TbShopTableQueryCriteria criteria, Pageable pageable){
if (criteria.getAreaId() == 0){
public Map<String, Object> queryAll(TbShopTableQueryCriteria criteria, Pageable pageable) {
if (criteria.getAreaId() == 0) {
criteria.setAreaId(null);
}
Page<TbShopTable> page = tbShopTableRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
Page<TbShopTable> page = tbShopTableRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
for (TbShopTable date : page.getContent()) {
if (!"".equals(date.getQrcode())){
date.setQrcode(QRCODE+date.getQrcode().trim());
if (!"".equals(date.getQrcode())) {
date.setQrcode(QRCODE + date.getQrcode().trim());
}
}
HashMap<String, Object> map = new HashMap<>();
map.put("content",page.getContent());
map.put("totalElements",page.getTotalElements());
map.put("content", page.getContent());
map.put("totalElements", page.getTotalElements());
return map;
}
@Override
public Map<String,Object> queryAllNoPage(TbShopTableQueryCriteria criteria){
public Map<String, Object> queryAllNoPage(TbShopTableQueryCriteria criteria) {
if (null == criteria.getAreaId() || criteria.getAreaId() == 0) {
criteria.setAreaId(null);
}
List<TbShopTable> tbShopTableList = tbShopTableRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder));
ArrayList<Map<String, Object>> infoList = new ArrayList<>();
for (TbShopTable date : tbShopTableList) {
if (!"".equals(date.getQrcode())){
date.setQrcode(QRCODE+date.getQrcode().trim());
Map<String, Object> itemMap = BeanUtil.beanToMap(date, false, false);
if (!"".equals(date.getQrcode())) {
itemMap.put("qrcode", QRCODE + date.getQrcode().trim());
itemMap.put("tableId", date.getQrcode());
}
infoList.add(itemMap);
}
int i = tbShopTableRepository.countAllByShopId(criteria.getShopId());
HashMap<String, Object> map = new HashMap<>();
map.put("content",tbShopTableList);
map.put("total",i);
map.put("content", infoList);
map.put("total", i);
return map;
}
@Override
public List<TbShopTableDto> queryAll(TbShopTableQueryCriteria criteria){
return tbShopTableMapper.toDto(tbShopTableRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
public List<TbShopTableDto> queryAll(TbShopTableQueryCriteria criteria) {
return tbShopTableMapper.toDto(tbShopTableRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
}
@Override
@ -105,7 +154,7 @@ public class TbShopTableServiceImpl implements TbShopTableService {
@Transactional
public TbShopTableDto findById(Integer id) {
TbShopTable tbShopTable = tbShopTableRepository.findById(id).orElseGet(TbShopTable::new);
ValidationUtil.isNull(tbShopTable.getId(),"TbShopTable","id",id);
ValidationUtil.isNull(tbShopTable.getId(), "TbShopTable", "id", id);
return tbShopTableMapper.toDto(tbShopTable);
}
@ -113,14 +162,14 @@ public class TbShopTableServiceImpl implements TbShopTableService {
public void binding(TbShopTable resources) {
//判是否绑定过
TbShopTable byQrcode = tbShopTableRepository.findByQrcode(resources.getQrcode());
if (byQrcode != null){
if (byQrcode != null) {
throw new BadRequestException("已绑定");
}
TbShopTable tbShopTable = tbShopTableRepository.findById(resources.getId()).orElseGet(TbShopTable::new);
if (tbShopTable.getId() == null){
if (tbShopTable.getId() == null) {
throw new BadRequestException("找不到台桌");
}
ValidationUtil.isNull( tbShopTable.getId(),"TbShopTable","id",resources.getId());
ValidationUtil.isNull(tbShopTable.getId(), "TbShopTable", "id", resources.getId());
tbShopTable.copy(resources);
tbShopTableRepository.save(tbShopTable);
}
@ -139,7 +188,7 @@ public class TbShopTableServiceImpl implements TbShopTableService {
@Transactional(rollbackFor = Exception.class)
public void update(TbShopTable resources) {
TbShopTable tbShopTable = tbShopTableRepository.findById(resources.getId()).orElseGet(TbShopTable::new);
ValidationUtil.isNull( tbShopTable.getId(),"TbShopTable","id",resources.getId());
ValidationUtil.isNull(tbShopTable.getId(), "TbShopTable", "id", resources.getId());
tbShopTable.copy(resources);
tbShopTableRepository.save(tbShopTable);
}
@ -155,9 +204,9 @@ public class TbShopTableServiceImpl implements TbShopTableService {
public void download(List<TbShopTableDto> all, HttpServletResponse response) throws IOException {
List<Map<String, Object>> list = new ArrayList<>();
for (TbShopTableDto tbShopTable : all) {
Map<String,Object> map = new LinkedHashMap<>();
map.put(" name", tbShopTable.getName());
map.put(" shopId", tbShopTable.getShopId());
Map<String, Object> map = new LinkedHashMap<>();
map.put(" name", tbShopTable.getName());
map.put(" shopId", tbShopTable.getShopId());
map.put("客座数,允许的客座数量", tbShopTable.getMaxCapacity());
map.put("台桌排序", tbShopTable.getSort());
map.put("区域Id", tbShopTable.getAreaId());
@ -168,10 +217,589 @@ public class TbShopTableServiceImpl implements TbShopTableService {
map.put("当type=0时amount生效,为台桌的低消金额", tbShopTable.getAmount());
map.put("当type=2时perhour生效为计时类型,每小时收款金额", tbShopTable.getPerhour());
map.put("台桌展示图---预留", tbShopTable.getView());
map.put(" createdAt", tbShopTable.getCreatedAt());
map.put(" updatedAt", tbShopTable.getUpdatedAt());
map.put(" createdAt", tbShopTable.getCreatedAt());
map.put(" updatedAt", tbShopTable.getUpdatedAt());
list.add(map);
}
FileUtil.downloadExcel(list, response);
}
@Override
public TbCashierCart updateCart(UpdateCartDTO updateCartDTO) {
TbCashierCart tbCashierCart = cashierCartMapper.selectById(updateCartDTO.getCartId());
if (tbCashierCart == null) {
throw new BadRequestException("购物车商品不存在");
}
if (updateCartDTO.getNum() == 0) {
cashierCartRepository.deleteById(updateCartDTO.getCartId());
return null;
}
TbProductSku productSku = productMapper.selectSkuByIdAndShopId(updateCartDTO.getShopId(), updateCartDTO.getSkuId());
TbProduct product = productMapper.selectByIdAndShopId(updateCartDTO.getShopId(), updateCartDTO.getProductId());
if (product == null || productSku == null) {
throw new BadRequestException("商品不存在或已下架, id: " + updateCartDTO.getSkuId());
}
tbCashierCart.setCoverImg(product.getCoverImg());
tbCashierCart.setCreatedAt(System.currentTimeMillis());
tbCashierCart.setIsSku(product.getTypeEnum());
tbCashierCart.setName(product.getName());
tbCashierCart.setProductId(String.valueOf(product.getId()));
tbCashierCart.setSalePrice(productSku.getSalePrice());
tbCashierCart.setSkuId(productSku.getId().toString());
tbCashierCart.setTradeDay(DateUtils.getDay());
tbCashierCart.setStatus("create");
tbCashierCart.setSalePrice(productSku.getSalePrice());
tbCashierCart.setTotalAmount(new BigDecimal(updateCartDTO.getNum()).multiply(productSku.getSalePrice()));
if (tbCashierCart.getIsPack().equals("false")) {
tbCashierCart.setPackFee(BigDecimal.ZERO);
} else {
tbCashierCart.setPackFee(new BigDecimal(updateCartDTO.getNum()).multiply(product.getPackFee()));
tbCashierCart.setTotalAmount(tbCashierCart.getTotalAmount().add(tbCashierCart.getPackFee()));
}
if (tbCashierCart.getIsGift().equals("true")) {
tbCashierCart.setTotalAmount(BigDecimal.ZERO);
}
tbCashierCart.setTotalNumber(updateCartDTO.getNum());
tbCashierCart.setNumber(updateCartDTO.getNum());
tbCashierCart.setCategoryId(product.getCategoryId());
cashierCartRepository.save(tbCashierCart);
return tbCashierCart;
}
@Override
public TbCashierCart addCartForUser(AddCartDTO addCartDTO) {
TbProductSku productSku = productMapper.selectSkuByIdAndShopId(addCartDTO.getShopId(), addCartDTO.getSkuId());
TbProduct product = productMapper.selectByIdAndShopId(addCartDTO.getShopId(), addCartDTO.getProductId());
if (product == null || productSku == null) {
throw new BadRequestException("商品不存在或已下架, id: " + addCartDTO.getSkuId());
}
if ((product.getIsDistribute().equals(1) && product.getStockNumber() < 1)
|| (!product.getIsDistribute().equals(1) && productSku.getStockNumber() < 1)
) {
throw new BadRequestException("商品库存不足");
}
TbShopTable shopTable = tbShopTableRepository.findByQrcode(addCartDTO.getTableId());
if (shopTable == null) {
throw new BadRequestException("桌码不存在,桌码" + addCartDTO.getTableId());
}
LambdaQueryWrapper<TbCashierCart> query = new LambdaQueryWrapper<TbCashierCart>().eq(TbCashierCart::getShopId, addCartDTO.getShopId())
.eq(TbCashierCart::getTableId, addCartDTO.getTableId());
if (addCartDTO.getVipUserId() != null) {
query.eq(TbCashierCart::getUserId, addCartDTO.getVipUserId());
} else {
query.isNull(TbCashierCart::getUserId);
}
TbCashierCart tbCashierCart = cashierCartMapper.selectOne(query);
// 首次加入
if (tbCashierCart == null) {
tbCashierCart = new TbCashierCart();
tbCashierCart.setUserId(addCartDTO.getVipUserId());
tbCashierCart.setCoverImg(product.getCoverImg());
tbCashierCart.setCreatedAt(System.currentTimeMillis());
tbCashierCart.setIsSku(product.getTypeEnum());
tbCashierCart.setTableId(Long.valueOf(addCartDTO.getTableId()));
tbCashierCart.setName(product.getName());
tbCashierCart.setProductId(String.valueOf(product.getId()));
tbCashierCart.setSalePrice(productSku.getSalePrice());
tbCashierCart.setSkuId(productSku.getId().toString());
tbCashierCart.setMasterId(addCartDTO.getMasterId());
tbCashierCart.setShopId(String.valueOf(addCartDTO.getShopId()));
tbCashierCart.setTradeDay(DateUtils.getDay());
tbCashierCart.setStatus("create");
tbCashierCart.setIsPack(String.valueOf(addCartDTO.isPack()));
tbCashierCart.setIsGift(String.valueOf(addCartDTO.isGift()));
tbCashierCart.setSalePrice(productSku.getSalePrice());
tbCashierCart.setTotalAmount(new BigDecimal(addCartDTO.getNum()).multiply(productSku.getSalePrice()));
if (!addCartDTO.isPack()) {
tbCashierCart.setPackFee(BigDecimal.ZERO);
} else {
tbCashierCart.setPackFee(new BigDecimal(addCartDTO.getNum()).multiply(product.getPackFee()));
tbCashierCart.setTotalAmount(tbCashierCart.getTotalAmount().add(tbCashierCart.getPackFee()));
}
if (addCartDTO.isGift()) {
tbCashierCart.setTotalAmount(BigDecimal.ZERO);
}
tbCashierCart.setTotalNumber(addCartDTO.getNum());
tbCashierCart.setNumber(addCartDTO.getNum());
tbCashierCart.setCategoryId(product.getCategoryId());
cashierCartRepository.save(tbCashierCart);
} else {
tbCashierCart.setTotalAmount(new BigDecimal(addCartDTO.getNum()).multiply(productSku.getSalePrice()));
if (!addCartDTO.isPack()) {
tbCashierCart.setPackFee(BigDecimal.ZERO);
} else {
tbCashierCart.setPackFee(new BigDecimal(addCartDTO.getNum()).multiply(product.getPackFee()));
tbCashierCart.setTotalAmount(tbCashierCart.getTotalAmount().add(tbCashierCart.getPackFee()));
}
if (addCartDTO.isGift()) {
tbCashierCart.setTotalAmount(BigDecimal.ZERO);
}
tbCashierCart.setIsPack(String.valueOf(addCartDTO.isPack()));
tbCashierCart.setIsGift(String.valueOf(addCartDTO.isGift()));
tbCashierCart.setTotalNumber(addCartDTO.getNum());
tbCashierCart.setNumber(addCartDTO.getNum());
// 数量0删除
if (tbCashierCart.getNumber() == 0) {
cashierCartRepository.deleteById(tbCashierCart.getId());
return null;
}
tbCashierCart.setUpdatedAt(DateUtil.current());
cashierCartRepository.save(tbCashierCart);
}
return tbCashierCart;
}
@Override
public void removeCart(RemoveCartDTO removeCartDTO) {
// 会员点单
cashierCartMapper.delete(new LambdaQueryWrapper<TbCashierCart>().eq(TbCashierCart::getShopId, removeCartDTO.getShopId())
.eq(TbCashierCart::getId, removeCartDTO.getCartId()));
}
@Override
public void clearCart(ClearCartDTO clearCartDTO) {
if (clearCartDTO.getVipUserId() != null) {
cashierCartMapper.delete(new LambdaQueryWrapper<TbCashierCart>().eq(TbCashierCart::getShopId, clearCartDTO.getShopId())
.eq(TbCashierCart::getTableId, clearCartDTO.getTableId())
.eq(TbCashierCart::getUserId, clearCartDTO.getVipUserId()));
} else {
cashierCartMapper.delete(new LambdaQueryWrapper<TbCashierCart>().eq(TbCashierCart::getShopId, clearCartDTO.getShopId())
.eq(TbCashierCart::getTableId, clearCartDTO.getTableId())
.eq(TbCashierCart::getMasterId, clearCartDTO.getMasterId())
.isNull(TbCashierCart::getUserId));
}
tbShopTableRepository.deleteByTableIdAndShopId(clearCartDTO.getTableId(), clearCartDTO.getShopId());
}
@Override
public com.baomidou.mybatisplus.extension.plugins.pagination.Page<TbCashierCart> getCart(Long tableId, Integer page, Integer size, Integer shopId, Integer vipUserId) {
LambdaQueryWrapper<TbCashierCart> queryWrapper = new LambdaQueryWrapper<TbCashierCart>()
.eq(TbCashierCart::getTableId, tableId)
.eq(TbCashierCart::getStatus, "create")
.eq(TbCashierCart::getShopId, shopId);
if (vipUserId != null) {
queryWrapper.eq(TbCashierCart::getUserId, vipUserId);
}else {
queryWrapper.isNull(TbCashierCart::getUserId);
}
com.baomidou.mybatisplus.extension.plugins.pagination.Page<TbCashierCart> cartPage = cashierCartMapper
.selectPage(new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, size), queryWrapper);
List<TbCashierCart> records = cartPage.getRecords();
ArrayList<Integer> skuIds = new ArrayList<>();
records.forEach(item -> {
skuIds.add(Integer.valueOf(item.getSkuId()));
});
if (!skuIds.isEmpty()) {
List<TbProductSku> skuList = productSkuRepository.findAllById(skuIds);
HashMap<String, TbProductSku> skuMap = new HashMap<>();
skuList.forEach(item -> skuMap.put(item.getId().toString(), item));
ArrayList<Map<String, Object>> infos = new ArrayList<>();
records.forEach(item -> {
Map<String, Object> map = BeanUtil.beanToMap(item, false, false);
TbProductSku tbProductSku = skuMap.get(item.getSkuId());
map.put("specSnap", tbProductSku != null ? tbProductSku.getSpecSnap() : null);
infos.add(map);
});
com.baomidou.mybatisplus.extension.plugins.pagination.Page copyPage = BeanUtil.copyProperties(cartPage, com.baomidou.mybatisplus.extension.plugins.pagination.Page.class);
copyPage.setRecords(infos);
return copyPage;
}
return cartPage;
}
@Override
public void pack(PackCartDTO packCartDTO) {
LambdaQueryWrapper<TbCashierCart> queryWrapper = new LambdaQueryWrapper<TbCashierCart>()
.eq(TbCashierCart::getTableId, packCartDTO.getTableId())
.eq(TbCashierCart::getShopId, packCartDTO.getShopId())
.eq(TbCashierCart::getStatus, "create");
if (packCartDTO.getVipUserId() != null) {
queryWrapper.eq(TbCashierCart::getUserId, packCartDTO.getVipUserId());
} else {
queryWrapper.isNull(TbCashierCart::getUserId);
}
List<TbCashierCart> tbCashierCarts = cashierCartMapper.selectList(queryWrapper);
tbCashierCarts.forEach(item -> {
if (packCartDTO.getState().equals(0) && item.getIsPack().equals("true")) {
item.setIsPack("false");
item.setTotalAmount(item.getTotalAmount().subtract(item.getPackFee()));
} else {
item.setIsPack("true");
item.setTotalAmount(item.getTotalAmount().add(item.getPackFee()));
}
cashierCartMapper.updateById(item);
});
}
@Override
public Object createOrder(CreateOrderDTO createOrderDTO) {
String day = DateUtils.getDay();
LambdaQueryWrapper<TbCashierCart> queryWrapper = new LambdaQueryWrapper<TbCashierCart>()
.eq(TbCashierCart::getShopId, createOrderDTO.getShopId())
.eq(TbCashierCart::getTableId, createOrderDTO.getTableId())
.eq(TbCashierCart::getStatus, "create");
if (createOrderDTO.getVipUserId() != null) {
queryWrapper.eq(TbCashierCart::getUserId, createOrderDTO.getVipUserId());
}else {
queryWrapper.eq(TbCashierCart::getMasterId, createOrderDTO.getMasterId())
.isNull(TbCashierCart::getUserId);
}
List<TbCashierCart> cashierCarts = cashierCartMapper
.selectList(queryWrapper);
if (cashierCarts.isEmpty()) {
throw new BadRequestException("购物车为空,请先添加商品");
}
BigDecimal totalAmount = BigDecimal.ZERO;
BigDecimal packAMount = BigDecimal.ZERO;
BigDecimal feeAmount = BigDecimal.ZERO;
BigDecimal saleAmount = BigDecimal.ZERO;
List<TbOrderDetail> orderDetails = new ArrayList<>();
Integer orderId = null;
for (TbCashierCart cashierCart : cashierCarts) {
totalAmount = totalAmount.add(cashierCart.getTotalAmount());
packAMount = packAMount.add(cashierCart.getPackFee());
feeAmount = cashierCart.getPackFee();
TbProductSku productSku = productSkuRepository.findById(Integer.valueOf(cashierCart.getSkuId())).orElse(null);
TbOrderDetail orderDetail = new TbOrderDetail();
if (Objects.nonNull(productSku)) {
saleAmount = saleAmount.add(productSku.getSalePrice());
orderDetail.setProductSkuName(productSku.getSpecSnap());
}
orderDetail.setCreateTime(DateUtil.date().toTimestamp());
orderDetail.setNum(cashierCart.getNumber());
orderDetail.setPrice(cashierCart.getSalePrice());
orderDetail.setPriceAmount(cashierCart.getTotalAmount());
orderDetail.setProductId(Integer.valueOf(cashierCart.getProductId()));
orderDetail.setProductSkuId(Integer.valueOf(cashierCart.getSkuId()));
orderDetail.setProductName(cashierCart.getName());
orderDetail.setShopId(Integer.valueOf(cashierCart.getShopId()));
orderDetail.setPackAmount(cashierCart.getPackFee());
orderDetail.setStatus("unpaid");
orderDetail.setProductImg(cashierCart.getCoverImg());
orderDetails.add(orderDetail);
if (cashierCart.getOrderId() != null) {
orderId = cashierCart.getOrderId();
}
}
TbOrderInfo orderInfo = null;
if (orderId != null) {
orderInfo = orderInfoMapper.selectById(orderId);
}
// 修改订单信息
if (orderInfo != null) {
// 删除历史订单
orderDetailMapper.delete(new LambdaQueryWrapper<TbOrderDetail>().eq(TbOrderDetail::getOrderId, orderId));
orderInfo.setUpdatedAt(System.currentTimeMillis());
orderInfo.setSettlementAmount(totalAmount);
orderInfo.setAmount(totalAmount);
orderInfo.setOriginAmount(totalAmount);
orderInfo.setStatus("unpaid");
orderInfo.setOrderAmount(totalAmount);
orderInfo.setRemark(createOrderDTO.getNote());
orderInfo.setFreightAmount(feeAmount);
orderInfo.setProductAmount(saleAmount);
orderInfo.setTradeDay(DateUtils.getDay());
orderInfoMapper.updateById(orderInfo);
}else {
String orderNo = generateOrderNumber();
orderInfo = new TbOrderInfo();
orderInfo.setOrderNo(orderNo);
orderInfo.setAmount(totalAmount);
orderInfo.setPackFee(packAMount);
orderInfo.setSettlementAmount(totalAmount);
orderInfo.setOriginAmount(totalAmount);
orderInfo.setProductAmount(saleAmount);
orderInfo.setOrderAmount(totalAmount);
orderInfo.setFreightAmount(feeAmount);
orderInfo.setTableId(createOrderDTO.getTableId());
orderInfo.setSendType("table");
orderInfo.setOrderType("cash");
orderInfo.setShopId(createOrderDTO.getShopId().toString());
orderInfo.setRefundAble(1);
orderInfo.setTradeDay(day);
orderInfo.setMasterId(createOrderDTO.getMasterId());
orderInfo.setRemark(createOrderDTO.getNote());
}
// 更新取餐号
orderInfo.setOutNumber(updateOutNumber(String.valueOf(createOrderDTO.getShopId())).toString());
orderInfoMapper.insert(orderInfo);
// 添加订单详细数据
orderId = orderInfo.getId();
for (TbOrderDetail orderDetail : orderDetails) {
orderDetail.setOrderId(orderId);
orderDetailMapper.insert(orderDetail);
}
// 更新购物车记录的orderId
// 是否是第一次添加的商品
boolean isFirst = true;
for (TbCashierCart cashierCart : cashierCarts) {
TbProduct product = productMapper.selectById(cashierCart.getProductId());
TbProductSku productSku = productSkuRepository.findById(Integer.valueOf(cashierCart.getSkuId())).orElse(null);
log.info("下单,开始校验库存预警,购物车id:{}", cashierCart.getId());
CompletableFuture.runAsync(() -> checkWarnLineAndSendMsg(productSku, product, Integer.valueOf(cashierCart.getShopId()), cashierCart.getNumber()));
// 已经添加的商品修改数量
isFirst = updateStock(cashierCart);
cashierCart.setOrderId(orderId);
cashierCart.setUpdatedAt(System.currentTimeMillis());
cashierCartMapper.updateById(cashierCart);
}
if (isFirst) {
redisTemplate.delete("SHOP:CODE:USER:pc:" + createOrderDTO.getShopId() + ":"
+ day + ":" + createOrderDTO.getTableId() + ":" + (createOrderDTO.getVipUserId() == null ? "" : createOrderDTO.getVipUserId()));
}
// 推送耗材信息
pushConsMsg(orderInfo, cashierCarts);
return orderInfo;
}
/**
* 增加库存
* @param productId 商品id
* @param skuId sku
* @param addNum 增加的库存数量
*/
public void incrStock(Integer productId, Integer skuId, Integer addNum) {
TbProduct product = productMapper.selectById(productId);
if (product.getIsDistribute() == 1) {
productMapper.incrStock(product.getId(), addNum);
}else {
producSkutMapper.incrStock(skuId, addNum);
}
}
/**
* 减少库存
* @param productId 商品数据
* @param skuId sku
* @param decrNum 减少的数量
*/
public void decrStock(Integer productId, String skuId, int decrNum) {
TbProduct product = productMapper.selectById(productId);
if (product.getIsDistribute() == 1) {
if (product.getIsStock() == 1) {
if (productMapper.decrStock(productId, decrNum) < 1) {
throw new BadRequestException("库存不足,下单失败");
}
}else {
productMapper.decrStockUnCheck(productId, decrNum);
}
}else {
if (product.getIsStock() == 1) {
if (producSkutMapper.decrStock(String.valueOf(skuId), decrNum) < 1) {
throw new BadRequestException("库存不足,下单失败");
}
}else {
producSkutMapper.decrStockUnCheck(String.valueOf(skuId), decrNum);
}
}
}
/**
* 推送耗材消耗信息
*/
private void pushConsMsg(TbOrderInfo orderInfo, List<TbCashierCart> cashierCarts) {
log.info("创建订单发送更新耗材消息订单id{}", orderInfo.getId());
//修改耗材数据
JSONObject jsonObject = new JSONObject();
jsonObject.put("orderId", orderInfo.getId());
jsonObject.put("type", "create");
rabbitTemplate.convertAndSend(RabbitConstants.CONS_COLLECT_PUT, RabbitConstants.CONS_COLLECT_ROUTINGKEY_PUT,
jsonObject.toJSONString(), new CorrelationData(UUID.randomUUID().toString()));
ThreadUtil.execAsync(() -> {
ThreadUtil.sleep(5, TimeUnit.SECONDS);
for (TbCashierCart cashierCart : cashierCarts) {
JSONObject objectMsg = new JSONObject();
objectMsg.put("skuId", Integer.valueOf(cashierCart.getSkuId()));
objectMsg.put("shopId", Integer.valueOf(cashierCart.getShopId()));
rabbitTemplate.convertAndSend(RabbitConstants.CONS_MSG_COLLECT_PUT, RabbitConstants.CONS_MSG_COLLECT_ROUTINGKEY_PUT,
objectMsg.toJSONString(), new CorrelationData(UUID.randomUUID().toString()));
}
});
}
/**
* 更新库存
* @param cashierCart 购物车
* @return 是否是第一次添加的商品
*/
private boolean updateStock(TbCashierCart cashierCart) {
if (cashierCart.getOrderId() != null) {
String message = redisTemplate.opsForValue().get(RedisConstant.ORDER_PRODUCT_NUM + cashierCart.getId());
if (message != null) {
int lastNum = Integer.parseInt(message);
// 数量减少, 返还库存
if (lastNum > cashierCart.getNumber()) {
incrStock(Integer.parseInt(cashierCart.getProductId()), Integer.parseInt(cashierCart.getSkuId()), lastNum - cashierCart.getNumber());
} else {
decrStock(Integer.parseInt(cashierCart.getProductId()), cashierCart.getSkuId(), cashierCart.getNumber() - lastNum);
}
redisTemplate.opsForValue().set(RedisConstant.ORDER_PRODUCT_NUM + cashierCart.getId(), cashierCart.getNumber().toString(), 24 * 60 * 60, TimeUnit.SECONDS);
}
return false;
// 首次添加的商品
} else {
redisTemplate.opsForValue().set(RedisConstant.ORDER_PRODUCT_NUM + cashierCart.getId(), cashierCart.getNumber().toString(), 24 * 60 * 60, TimeUnit.SECONDS);
// 修改库存
decrStock(Integer.parseInt(cashierCart.getProductId()), cashierCart.getSkuId(), cashierCart.getNumber());
return true;
}
}
/**
* 更新取餐号
* @param shopId 店铺id
* @return 当前取餐号
*/
public Integer updateOutNumber(String shopId) {
JSONObject object = new JSONObject();
String outNumber = redisTemplate.opsForValue().get(RedisConstant.OUT_NUMBER.concat(shopId));
Integer number = 1;
if (Objects.isNull(outNumber)) {
object.put("outNumber", number);
object.put("times", DateUtils.getDay());
} else {
object = JSONObject.parseObject(outNumber);
if (object.getString("times").equals(DateUtils.getDay())) {
number = object.getInteger("outNumber") + 1;
object.put("outNumber", number);
} else {
object.put("outNumber", number);
object.put("times", DateUtils.getDay());
}
}
redisTemplate.opsForValue().set(RedisConstant.OUT_NUMBER.concat(shopId), object.toString());
return number;
}
/**
* 校验商品库存警戒线并通知商户
*
* @param productSku sku
*/
private void checkWarnLineAndSendMsg(TbProductSku productSku, TbProduct product, Integer shopId, Integer num) {
TbShopInfo shopInfo = shopInfoRepository.getById(shopId);
if (productSku.getWarnLine() == null) {
return;
}
if (product.getIsStock() == null || product.getIsStock() != 1) {
return;
}
if (productSku.getStockNumber() == null) {
productSku.setStockNumber((double) 0);
}
if (product.getStockNumber() == null) {
product.setStockNumber(0);
}
if (
(product.getIsDistribute() == 1 && product.getStockNumber() - num <= productSku.getWarnLine())
|| (product.getIsDistribute() != 1) && productSku.getStockNumber() - num <= productSku.getWarnLine()
) {
List<TbShopOpenId> openIdList = shopOpenIdMapper.selectList(new LambdaQueryWrapper<TbShopOpenId>()
.eq(TbShopOpenId::getShopId, shopId)
.eq(TbShopOpenId::getStatus, 1)
.and((queryWrapper) -> queryWrapper.eq(TbShopOpenId::getType, ShopWxMsgTypeEnum.ALL_MSG.getType())
.or().eq(TbShopOpenId::getType, ShopWxMsgTypeEnum.STOCK_MSG.getType()))
.groupBy(TbShopOpenId::getOpenId)
);
wxMsgUtils.aboardStockMsg(shopInfo.getShopName(), shopId, product.getName(),
product.getIsDistribute() == 1 ? product.getStockNumber()-num : (int) (productSku.getStockNumber() - num));
}
}
public String generateOrderNumber() {
String date = DateUtils.getSdfTimes();
Random random = new Random();
int randomNum = random.nextInt(900) + 100;
return "DD" + date + randomNum;
}
public synchronized String generateOrderCode(String day, String clientType, String shopId) {
String code = redisUtils.get("SHOP:CODE:" + clientType + ":" + shopId + ":" + day) + "";
// 使用顺序递增的计数器生成取餐码
String orderCode = "";
if (StringUtils.isEmpty(code) || "null".equals(code)) {
orderCode = "1";
redisTemplate.opsForValue().set("SHOP:CODE:" + clientType + ":" + shopId + ":" + day, "1");
} else {
orderCode = String.valueOf(Integer.parseInt(code) + 1);
}
redisTemplate.opsForValue().set("SHOP:CODE:" + clientType + ":" + shopId + ":" + day, "#" + Integer.parseInt(code.replace("#", "")) + 2);
boolean flag = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent("SHOP:CODE:SET" + clientType + ":" + shopId + ":" + day, orderCode));
if (flag) {
return generateOrderCode(day, clientType, shopId);
}
// 增加计数器
return orderCode;
}
private final StringRedisTemplate redisTemplate;
@Override
public Object getMasterId(Integer shopId, Long tableId, Integer vipUserId) {
String account = tokenProvider.getSubject();
if (account == null) {
throw new BadRequestException("token解析失败");
}
TbMerchantAccount merchantAccount = merchantAccountMapper.selectOne(new LambdaQueryWrapper<TbMerchantAccount>().eq(TbMerchantAccount::getAccount, account));
String day = DateUtils.getDay();
JSONObject jsonObject = new JSONObject();
String key = "SHOP:CODE:USER:pc" + ":" + shopId + ":" + day + ":" + tableId + ":" + (vipUserId == null ? "" : vipUserId);
String userCode = redisTemplate.opsForValue().get(key);
if (StringUtils.isEmpty(userCode) || "null".equals(userCode) || "#null".equals(userCode)) {
String code = "#" + generateOrderCode(day, "pc", String.valueOf(shopId));
redisTemplate.opsForValue().set(key, code);
jsonObject.put("masterId", code);
} else {
jsonObject.put("masterId", userCode);
}
return jsonObject;
}
}

View File

@ -104,4 +104,6 @@ public interface TbProductService {
* @param num 数量
*/
void returnStockByPro(Integer productId, Integer productSkuId, Integer num);
Object activateProduct(Integer page, Integer size, Integer categoryId, Integer shopId, Integer productId);
}

View File

@ -0,0 +1,23 @@
package cn.ysk.cashier.service.shop;
import cn.ysk.cashier.dto.shop.ShopInfoUpdateDTO;
import cn.ysk.cashier.dto.shop.ShopMsgRemoveDTO;
import cn.ysk.cashier.dto.shop.ShopMsgStateDTO;
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
import cn.ysk.cashier.pojo.shop.TbFullShopId;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.HashMap;
import java.util.Optional;
public interface MsgService {
Page<TbFullShopId> all(Integer page, Integer size, Integer shopId, String nickName, String openId, Integer state, Integer type);
Optional<Boolean> updateShopState(ShopMsgStateDTO shopMsgStateDTO);
Optional<Boolean> removeSubUser(ShopMsgRemoveDTO shopMsgRemoveDTO);
Optional<Boolean> updateInfo(ShopInfoUpdateDTO shopInfoUpdateDTO);
HashMap<String, Object> getInfo(Integer shopId, Integer type);
}

View File

@ -15,9 +15,12 @@
*/
package cn.ysk.cashier.service.shop;
import cn.ysk.cashier.dto.shoptable.*;
import cn.ysk.cashier.pojo.order.TbCashierCart;
import cn.ysk.cashier.pojo.shop.TbShopTable;
import cn.ysk.cashier.dto.shop.TbShopTableDto;
import cn.ysk.cashier.dto.shop.TbShopTableQueryCriteria;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.data.domain.Pageable;
import java.util.Map;
import java.util.List;
@ -92,4 +95,20 @@ public interface TbShopTableService {
* @throws IOException /
*/
void download(List<TbShopTableDto> all, HttpServletResponse response) throws IOException;
TbCashierCart addCartForUser(AddCartDTO addCartDTO);
void removeCart(RemoveCartDTO removeCartDTO);
void clearCart(ClearCartDTO clearCartDTO);
Page<TbCashierCart> getCart(Long tableId, Integer page, Integer size, Integer shopId, Integer vipUserId);
TbCashierCart updateCart(UpdateCartDTO updateCartDTO);
void pack(PackCartDTO packCartDTO);
Object createOrder(CreateOrderDTO createOrderDTO);
Object getMasterId(Integer shopId, Long tableId, Integer vipUserId);
}

View File

@ -5,18 +5,21 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.ysk.cashier.enums.ShopWxMsgTypeEnum;
import cn.ysk.cashier.mybatis.entity.TbShopMsgState;
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
import cn.ysk.cashier.mybatis.mapper.TbShopMsgStateMapper;
import cn.ysk.cashier.pojo.shop.TbShopInfo;
import cn.ysk.cashier.repository.shop.TbShopInfoRepository;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
@Data
@Slf4j
@ -27,21 +30,26 @@ public class WxAccountUtil {
@Value("${wx.ysk.secrete}")
private String secrete = "8492a7e8d55bbb1b57f5c8276ea1add0";
@Value("${wx.ysk.operationMsgTmpId}")
private String operationMsgTmpId ;
private String operationMsgTmpId;
@Value("${wx.ysk.warnMsgTmpId}")
private String warnMsgTmpId;
static LinkedHashMap<String,String> linkedHashMap=new LinkedHashMap<>();
private final TbShopMsgStateMapper shopMsgStateMapper;
private final TbShopInfoRepository shopInfoRepository;
static LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
static {
linkedHashMap.put("40001","获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口");
linkedHashMap.put("40003","不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID");
linkedHashMap.put("40014","不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口");
linkedHashMap.put("40037","不合法的 template_id");
linkedHashMap.put("43101","用户未订阅消息");
linkedHashMap.put("43107","订阅消息能力封禁");
linkedHashMap.put("43108","并发下发消息给同一个粉丝");
linkedHashMap.put("45168","命中敏感词");
linkedHashMap.put("47003","参数错误");
linkedHashMap.put("40001", "获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口");
linkedHashMap.put("40003", "不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID");
linkedHashMap.put("40014", "不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口");
linkedHashMap.put("40037", "不合法的 template_id");
linkedHashMap.put("43101", "用户未订阅消息");
linkedHashMap.put("43107", "订阅消息能力封禁");
linkedHashMap.put("43108", "并发下发消息给同一个粉丝");
linkedHashMap.put("45168", "命中敏感词");
linkedHashMap.put("47003", "参数错误");
}
@ -84,16 +92,16 @@ public class WxAccountUtil {
log.info("开始发送微信模板消息, 接收用户openId: {}, 消息数据: {}", toUserOpenId, data);
String accessToken = getAccessToken();
JSONObject object1=new JSONObject();
JSONObject object1 = new JSONObject();
object1.put("template_id", templateId);
object1.put("touser", toUserOpenId);
object1.put("data",data);
object1.put("data", data);
String response= HttpRequest.post("https://api.weixin.qq.com/cgi-bin/message/template/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")+"")){
String response = HttpRequest.post("https://api.weixin.qq.com/cgi-bin/message/template/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;
}
@ -104,23 +112,48 @@ public class WxAccountUtil {
public void sendOperationMsg(List<TbShopOpenId> openIds, String userName, String operationDesc) {
openIds.forEach(item -> {
Map<String, Object> data = new HashMap<String, Object>() {{
put("thing19", new HashMap<String, Object>(){{
put("thing19", new HashMap<String, Object>() {{
put("value", userName);
}});
put("thing8", new HashMap<String, Object>(){{
put("thing8", new HashMap<String, Object>() {{
put("value", operationDesc);
}});
put("time21", new HashMap<String, Object>(){{
put("time21", new HashMap<String, Object>() {{
put("value", DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss"));
}});
}};
log.info("开始发送敏感操作消息, 接收用户openId: {}, 操作用户: {}, 操作描述: {}", item.getOpenId(), userName, operationDesc);
try {
sendTemplateMsg(operationMsgTmpId, item.getOpenId(), data);
}catch (Exception e) {
} catch (Exception e) {
log.error("发送失败, openId: {}, 响应: {}", item.getOpenId(), e.getMessage());
}
});
}
public void sendStockMsg(String shopName, String productName, int stock, String openId, ShopWxMsgTypeEnum shopWxMsgTypeEnum, Integer shopId) {
stock = Math.max(stock, 0);
Integer finalStock = stock;
Map<String, Object> data = new HashMap<String, Object>() {{
put("thing22", new HashMap<String, Object>() {{
put("value", shopName);
}});
put("thing4", new HashMap<String, Object>() {{
put("value", productName);
}});
put("number5", new HashMap<String, Object>() {{
put("value", finalStock);
}});
}};
log.info("开始发送库存预警消息, 接收用户openId: {}, 消息数据: {}", openId, data);
try {
sendTemplateMsg(warnMsgTmpId, openId, data);
} catch (Exception e) {
log.error("发送失败, openId:{}, msg: {}", openId, e.getMessage());
}
}
}

View File

@ -1,15 +1,23 @@
package cn.ysk.cashier.utils;
import cn.ysk.cashier.enums.ShopWxMsgTypeEnum;
import cn.ysk.cashier.mybatis.entity.TbShopMsgState;
import cn.ysk.cashier.mybatis.entity.TbShopOpenId;
import cn.ysk.cashier.mybatis.mapper.TbShopMsgStateMapper;
import cn.ysk.cashier.mybatis.mapper.TbShopOpenIdMapper;
import cn.ysk.cashier.mybatis.service.TbShopMsgStateService;
import cn.ysk.cashier.mybatis.service.TbShopOpenIdService;
import cn.ysk.cashier.pojo.shop.TbShopInfo;
import cn.ysk.cashier.repository.shop.TbShopInfoRepository;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.function.Consumer;
@Component
@Slf4j
@ -20,14 +28,47 @@ public class WxMsgUtils {
private final RedisUtils redisUtils;
private final WxAccountUtil wxAccountUtil;
private final TbShopMsgStateService shopMsgStateService;
private final TbShopMsgStateMapper shopMsgStateMapper;
private final TbShopOpenIdMapper shopOpenIdMapper;
private final TbShopInfoRepository shopInfoRepository;
public WxMsgUtils(TbShopOpenIdService tbShopOpenIdService, RedisUtils redisUtils, WxAccountUtil wxAccountUtil) {
public WxMsgUtils(TbShopOpenIdService tbShopOpenIdService, RedisUtils redisUtils, WxAccountUtil wxAccountUtil, TbShopMsgStateService shopMsgStateService, TbShopMsgStateMapper shopMsgStateMapper, TbShopOpenIdMapper shopOpenIdMapper, TbShopInfoRepository shopInfoRepository) {
this.tbShopOpenIdService = tbShopOpenIdService;
this.redisUtils = redisUtils;
this.wxAccountUtil = wxAccountUtil;
this.shopMsgStateService = shopMsgStateService;
this.shopMsgStateMapper = shopMsgStateMapper;
this.shopOpenIdMapper = shopOpenIdMapper;
this.shopInfoRepository = shopInfoRepository;
}
public void aboardOperationMsg(String operationDesc) {
public boolean checkIsOpen(Integer shopId, ShopWxMsgTypeEnum shopWxMsgTypeEnum) {
TbShopMsgState allState = shopMsgStateMapper.selectOne(new LambdaQueryWrapper<TbShopMsgState>()
.eq(TbShopMsgState::getShopId, shopId)
.eq(TbShopMsgState::getState, 1)
.eq(TbShopMsgState::getType, ShopWxMsgTypeEnum.ALL_MSG.getType()));
if (allState == null) {
log.warn("店铺全局推送开关未开启");
return false;
}
TbShopMsgState currentState = shopMsgStateMapper.selectOne(new LambdaQueryWrapper<TbShopMsgState>()
.eq(TbShopMsgState::getShopId, shopId)
.eq(TbShopMsgState::getState, 1)
.eq(TbShopMsgState::getType, shopWxMsgTypeEnum.getType()));
if (currentState == null) {
log.warn("当前推送未开启: {}", shopWxMsgTypeEnum);
return false;
}
return true;
}
public void aboardOperationMsg(String operationDesc, Integer shopId1) {
if (!checkIsOpen(shopId1, ShopWxMsgTypeEnum.OPERATION_MSG)) {
return;
}
HttpServletRequest request = RequestHolder.getHttpServletRequest();
Object o = redisUtils.get("online-token-"+getToken(request));
@ -39,7 +80,13 @@ public class WxMsgUtils {
jsonObject = JSONObject.parseObject(jsonString);
shopId = (Integer) jsonObject.get("shopId");
nickName = jsonObject.get("nickName") == null ? "" : jsonObject.get("nickName").toString();
List<TbShopOpenId> openIds = tbShopOpenIdService.lambdaQuery().eq(TbShopOpenId::getShopId, shopId).list();
List<TbShopOpenId> openIds = tbShopOpenIdService.lambdaQuery()
.eq(TbShopOpenId::getShopId, shopId)
.eq(TbShopOpenId::getStatus, 1)
.and((queryWrapper) -> queryWrapper.eq(TbShopOpenId::getType, ShopWxMsgTypeEnum.ALL_MSG.getType())
.or().eq(TbShopOpenId::getType, ShopWxMsgTypeEnum.OPERATION_MSG.getType()))
.groupBy(TbShopOpenId::getOpenId)
.list();
log.info("即将开始推送敏感操作消息, 接收推送openId列表: {}", openIds);
String finalNickName = nickName;
wxAccountUtil.sendOperationMsg(openIds, finalNickName, operationDesc);
@ -48,6 +95,24 @@ public class WxMsgUtils {
}
}
public void aboardStockMsg(String shopName, Integer shopId, String proName, Integer stock) {
if (!checkIsOpen(shopId, ShopWxMsgTypeEnum.OPERATION_MSG)) {
return;
}
List<TbShopOpenId> openIds = tbShopOpenIdService.lambdaQuery()
.eq(TbShopOpenId::getShopId, shopId)
.eq(TbShopOpenId::getStatus, 1)
.and((queryWrapper) -> queryWrapper.eq(TbShopOpenId::getType, ShopWxMsgTypeEnum.ALL_MSG.getType())
.or().eq(TbShopOpenId::getType, ShopWxMsgTypeEnum.STOCK_MSG.getType()))
.groupBy(TbShopOpenId::getOpenId)
.list();
log.info("即将开始推送敏感操作消息, 接收推送openId列表: {}", openIds);
openIds.parallelStream().forEach(item -> {
wxAccountUtil.sendStockMsg(shopName, proName, stock, item.getOpenId(), ShopWxMsgTypeEnum.STOCK_MSG, shopId);
});
}
public String getToken(HttpServletRequest request) {
final String requestHeader = request.getHeader("Authorization");
if (requestHeader != null && requestHeader.startsWith("Bearer")) {

View File

@ -14,4 +14,5 @@ public class TbOrderSaleVO {
private Integer num;
private BigDecimal price;
private String status;
private Integer skuId;
}

View File

@ -134,7 +134,8 @@ public class TbOrderSalesCountByDayVo {
count();
}
public TbOrderSalesCountByDayVo(String productName, String productSkuName, String cateName,String unitName,BigDecimal price,
public TbOrderSalesCountByDayVo(String productName, String productSkuName,
String cateName,String unitName,BigDecimal price,
Long salesNum, Long refNum, Long num, BigDecimal salesAmount, BigDecimal refAmount, Integer productId, Integer productSkuId) {
this.productName = productName;
this.productSkuName = productSkuName;
@ -153,6 +154,7 @@ public class TbOrderSalesCountByDayVo {
public void count(){
salesNum=salesNum-refNum;
salesAmount=salesAmount.subtract(refAmount);

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.ysk.cashier.mybatis.mapper.TbShopMsgStateMapper">
<resultMap id="BaseResultMap" type="cn.ysk.cashier.mybatis.pojo.TbShopMsgStatetb">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="shop_id" column="shop_id" jdbcType="INTEGER"/>
<result property="type" column="type" jdbcType="INTEGER"/>
<result property="state" column="state" jdbcType="INTEGER"/>
<result property="create_time" column="create_time" jdbcType="TIMESTAMP"/>
<result property="update_time" column="update_time" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="Base_Column_List">
id,shop_id,type,
state,create_time,update_time
</sql>
</mapper>

View File

@ -12,11 +12,14 @@
<result property="create_time" column="create_time" jdbcType="TIMESTAMP"/>
<result property="update_time" column="update_time" jdbcType="TIMESTAMP"/>
<result property="type" column="type" jdbcType="TINYINT"/>
<result property="nickname" column="nickname" jdbcType="VARCHAR"/>
<result property="avatar" column="avatar" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
id,shop_id,open_id,
status,create_time,update_time,
type
type,nickname,avatar
</sql>
</mapper>

View File

@ -70,6 +70,7 @@ public interface QiNiuService {
* @return QiniuContent
*/
QiniuContent upload(MultipartFile file, CloudStorageConfig cloudStorageConfig);
QiniuContent uploadByte(byte[] bytes, CloudStorageConfig qiniuConfig);
/**
* 查询文件

View File

@ -148,6 +148,36 @@ public class QiNiuServiceImpl implements QiNiuService {
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public QiniuContent uploadByte(byte[] bytes, CloudStorageConfig qiniuConfig) {
if(qiniuConfig== null){
throw new BadRequestException("请先添加相应配置,再操作");
}
// 构造一个带指定Zone对象的配置类
try {
String url = OSSFactory.build(qiniuConfig).uploadSuffix(bytes, "png");
if(url != null){
//存入数据库
String[] str=url.split("/");
String fileName=str[str.length-1];
QiniuContent qiniuContent = new QiniuContent();
qiniuContent.setKey(fileName);
qiniuContent.setSuffix(fileName.split("\\.")[1]);
qiniuContent.setBucket(qiniuConfig.getBucketName());
qiniuContent.setSize(bytes.length+"");
qiniuContent.setType("公开");
qiniuContent.setUrl(url);
return qiniuContentRepository.save(qiniuContent);
}
return new QiniuContent();
} catch (Exception e) {
throw new BadRequestException(e.getMessage());
}
}
@Override
public QiniuContent findByContentId(Long id) {
QiniuContent qiniuContent = qiniuContentRepository.findById(id).orElseGet(QiniuContent::new);