Merge branch 'cc_20251030_fwb' into 'master'

数据看板

See merge request hangzhou/java/custom_zxjp!179
This commit is contained in:
苏竹红
2025-10-31 09:26:50 +00:00
12 changed files with 302 additions and 10 deletions

View File

@@ -310,9 +310,11 @@ public enum ErrorCodeEnum {
MESSAGE_NOT_HANDLED(1610008,"当前消息无需处理,请确认消息处理类型!",null), MESSAGE_NOT_HANDLED(1610008,"当前消息无需处理,请确认消息处理类型!",null),
MESSAGE_PUBLISH(1610009,"您选择通知任务正在发布中,请稍后重试!",null), MESSAGE_PUBLISH(1610009,"您选择通知任务正在发布中,请稍后重试!",null),
NOT_FLAGSHIP_STORE(16100005,"非直营店,无法跳过缴费阶段!",null), NOT_FLAGSHIP_STORE(1610010,"非直营店,无法跳过缴费阶段!",null),
NOT_FLAGSHIP_STORE_NOT_EXIST(16100006,"当前阶段加盟类型不能变更!",null), NOT_FLAGSHIP_STORE_NOT_EXIST(1610011,"当前阶段加盟类型不能变更!",null),
JOIN_MODE_NOT_ALLOW_OPERATE(16100007,"加盟部人员只能新建加盟店或联营店,请确认!",null), JOIN_MODE_NOT_ALLOW_OPERATE(1610012,"加盟部人员只能新建加盟店或联营店,请确认!",null),
STORE_NOT_FIND(1610013,"门店不存在",null),
; ;

View File

@@ -1,5 +1,6 @@
package com.cool.store.utils; package com.cool.store.utils;
import cn.hutool.core.bean.copier.CopyOptions;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import java.util.ArrayList; import java.util.ArrayList;
@@ -28,6 +29,18 @@ public class BeanUtil extends cn.hutool.core.bean.BeanUtil {
return result; return result;
} }
public static <T, R> List<R> toList(List<T> list, Class<R> clazz, CopyOptions copyOptions) {
if (list == null || list.isEmpty()) {
return Collections.emptyList();
}
List<R> result = new ArrayList<>(list.size());
for (T t : list) {
R r = toBean(t, clazz, copyOptions);
result.add(r);
}
return result;
}
public static <T, R> PageInfo<R> toPage(PageInfo<T> page, Class<R> clazz) { public static <T, R> PageInfo<R> toPage(PageInfo<T> page, Class<R> clazz) {
PageInfo<R> newPage = new PageInfo<>(); PageInfo<R> newPage = new PageInfo<>();
newPage.setPages(page.getPages()); newPage.setPages(page.getPages());

View File

@@ -0,0 +1,21 @@
package com.cool.store.dto.recipe;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* <p>
* 服务包菜品数据
* </p>
*
* @author wangff
* @since 2025/10/30
*/
@Data
public class LaunchDataDTO {
@ApiModelProperty("名称")
private String spName;
@ApiModelProperty("上新时间yyyy-MM-dd")
private String upSaleDate;
}

View File

@@ -0,0 +1,38 @@
package com.cool.store.dto.recipe;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* <p>
* 营收数据
* </p>
*
* @author wangff
* @since 2025/10/30
*/
@Data
public class RevenueDataDTO {
@ApiModelProperty("门店编码")
private String storeCode;
@ApiModelProperty("营业额")
private BigDecimal amt;
@ApiModelProperty("实收")
private BigDecimal receivedAmt;
@ApiModelProperty("营业时间yyyy-MM-dd")
private String businessDate;
@ApiModelProperty("服务包列表")
private List<LaunchDataDTO> otherLaunchDates;
@ApiModelProperty("菜品列表")
private List<LaunchDataDTO> otherRecipeLaunchDates;
}

View File

@@ -0,0 +1,28 @@
package com.cool.store.dto.recipe;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* <p>
* 营收数据查询DTO
* </p>
*
* @author wangff
* @since 2025/10/30
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RevenueDataQueryDTO {
@ApiModelProperty("门店编码")
private String storeCode;
@ApiModelProperty("业务时间开始")
private String businessDateFrom;
@ApiModelProperty("业务时间结束")
private String businessDateTo;
}

View File

@@ -0,0 +1,29 @@
package com.cool.store.request.recipe;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* <p>
* 营收数据Request
* </p>
*
* @author wangff
* @since 2025/10/30
*/
@Data
public class RevenueDataRequest {
@ApiModelProperty("门店id")
@NotBlank(message = "门店id不能为空")
private String storeId;
@ApiModelProperty("业务时间开始yyyy-MM-dd")
@NotBlank(message = "业务时间开始不能为空")
private String businessDateFrom;
@ApiModelProperty("业务时间结束yyyy-MM-dd")
@NotBlank(message = "业务时间结束不能为空")
private String businessDateTo;
}

View File

@@ -0,0 +1,21 @@
package com.cool.store.vo.recipe;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* <p>
* 服务包菜品数据
* </p>
*
* @author wangff
* @since 2025/10/30
*/
@Data
public class LaunchDataVO {
@ApiModelProperty("名称")
private String spName;
@ApiModelProperty("上新时间yyyy-MM-dd")
private String upSaleDate;
}

View File

@@ -0,0 +1,38 @@
package com.cool.store.vo.recipe;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
* <p>
* 营收数据VO
* </p>
*
* @author wangff
* @since 2025/10/30
*/
@Data
public class RevenueDataVO {
@ApiModelProperty("门店编码")
private String storeNum;
@ApiModelProperty("营业额")
private BigDecimal amt;
@ApiModelProperty("实收")
private BigDecimal receivedAmt;
@ApiModelProperty("营业时间yyyy-MM-dd")
private String businessDate;
@ApiModelProperty("服务包列表")
private List<LaunchDataVO> otherLaunchDates;
@ApiModelProperty("菜品列表")
private List<LaunchDataVO> otherRecipeLaunchDates;
}

View File

@@ -1,10 +1,10 @@
package com.cool.store.service; package com.cool.store.service;
import com.cool.store.dto.FoodTokenDTO; import com.cool.store.dto.FoodTokenDTO;
import com.cool.store.dto.GetAccessTokenDTO;
import com.cool.store.dto.store.StoreUserPositionDTO;
import com.cool.store.dto.store.StoreUserUpdateDTO; import com.cool.store.dto.store.StoreUserUpdateDTO;
import com.cool.store.request.recipe.RevenueDataRequest;
import com.cool.store.response.caipin.StoreUserResponse; import com.cool.store.response.caipin.StoreUserResponse;
import com.cool.store.vo.recipe.RevenueDataVO;
import java.util.List; import java.util.List;
@@ -31,4 +31,10 @@ public interface ThirdFoodService {
*/ */
StoreUserResponse pushStoreUser(List<StoreUserUpdateDTO> storeUserUpdateDTOList); StoreUserResponse pushStoreUser(List<StoreUserUpdateDTO> storeUserUpdateDTOList);
/**
* 查询门店营收实收数据
* @param request 营收数据Request
* @return 营收数据VO列表
*/
List<RevenueDataVO> getRevenueData(RevenueDataRequest request);
} }

View File

@@ -1,17 +1,22 @@
package com.cool.store.service.impl; package com.cool.store.service.impl;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject; import com.cool.store.dao.StoreDao;
import com.cool.store.dto.FoodTokenDTO; import com.cool.store.dto.FoodTokenDTO;
import com.cool.store.dto.GetAccessTokenDTO; import com.cool.store.dto.recipe.RevenueDataDTO;
import com.cool.store.dto.store.StoreUserPositionDTO; import com.cool.store.dto.recipe.RevenueDataQueryDTO;
import com.cool.store.dto.store.StoreUserUpdateDTO; import com.cool.store.dto.store.StoreUserUpdateDTO;
import com.cool.store.entity.StoreDO;
import com.cool.store.enums.ErrorCodeEnum; import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException; import com.cool.store.exception.ServiceException;
import com.cool.store.request.recipe.RevenueDataRequest;
import com.cool.store.response.caipin.StoreUserResponse; import com.cool.store.response.caipin.StoreUserResponse;
import com.cool.store.response.oppty.OpportunityApiResponse; import com.cool.store.response.oppty.OpportunityApiResponse;
import com.cool.store.service.ThirdFoodService; import com.cool.store.service.ThirdFoodService;
import com.cool.store.utils.BeanUtil;
import com.cool.store.utils.SignatureUtils; import com.cool.store.utils.SignatureUtils;
import com.cool.store.vo.recipe.RevenueDataVO;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@@ -24,9 +29,9 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.net.URI; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Objects;
/** /**
* @Author suzhuhong * @Author suzhuhong
@@ -45,6 +50,8 @@ public class ThirdFoodServiceImpl implements ThirdFoodService {
OkHttpClient okHttpClient; OkHttpClient okHttpClient;
@Resource @Resource
ObjectMapper objectMapper; ObjectMapper objectMapper;
@Resource
private StoreDao storeDao;
@Override @Override
@@ -60,6 +67,18 @@ public class ThirdFoodServiceImpl implements ThirdFoodService {
return executeApiCall(url, dto, StoreUserResponse.class); return executeApiCall(url, dto, StoreUserResponse.class);
} }
@Override
public List<RevenueDataVO> getRevenueData(RevenueDataRequest request) {
StoreDO storeDO = storeDao.getByStoreId(request.getStoreId());
if (Objects.isNull(storeDO)) {
throw new ServiceException(ErrorCodeEnum.STORE_NOT_FIND);
}
RevenueDataQueryDTO queryDTO = new RevenueDataQueryDTO(storeDO.getStoreNum(), request.getBusinessDateFrom(), request.getBusinessDateTo());
String url = "/v1/store/business";
List<RevenueDataDTO> list = executeApiCall(url, queryDTO, List.class);
return BeanUtil.toList(list, RevenueDataVO.class, CopyOptions.create().setFieldMapping(Collections.singletonMap("storeCode", "storeNum")));
}
private <T> T executeApiCall(String url, Object requestBody, Class<T> responseType) { private <T> T executeApiCall(String url, Object requestBody, Class<T> responseType) {
// 1. 打印请求前日志 // 1. 打印请求前日志

View File

@@ -0,0 +1,37 @@
package com.cool.store.controller.webb;
import com.cool.store.request.recipe.RevenueDataRequest;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.ThirdFoodService;
import com.cool.store.vo.recipe.RevenueDataVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* <p>
* 数据看板 前端控制器
* </p>
*
* @author wangff
* @since 2025/10/30
*/
@RestController
@RequestMapping("/pc/databoard")
@Api(tags = "数据看板")
@Slf4j
@RequiredArgsConstructor
public class DataBoardController {
private final ThirdFoodService thirdFoodService;
@ApiOperation("门店营收")
@PostMapping("/revenueData")
public ResponseResult<List<RevenueDataVO>> getStoreRevenueData(@RequestBody @Valid RevenueDataRequest request) {
return ResponseResult.success(thirdFoodService.getRevenueData(request));
}
}

View File

@@ -0,0 +1,40 @@
package com.cool.store.controller.webc;
import com.cool.store.request.recipe.RevenueDataRequest;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.ThirdFoodService;
import com.cool.store.vo.recipe.RevenueDataVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List;
/**
* <p>
* 数据看板 前端控制器
* </p>
*
* @author wangff
* @since 2025/10/30
*/
@RestController
@RequestMapping("/mini/databoard")
@Api(tags = "Mini数据看板")
@Slf4j
@RequiredArgsConstructor
public class MiniDataBoardController {
private final ThirdFoodService thirdFoodService;
@ApiOperation("门店营收")
@PostMapping("/revenueData")
public ResponseResult<List<RevenueDataVO>> getStoreRevenueData(@RequestBody @Valid RevenueDataRequest request) {
return ResponseResult.success(thirdFoodService.getRevenueData(request));
}
}