Преглед на файлове

feat:店铺预警模块curd

huangjinliang преди 3 дни
родител
ревизия
ed7aa838da

+ 16 - 0
fuintBackend/fuint-application/src/main/java/com/fuint/common/dto/ext/PageResult.java

@@ -0,0 +1,16 @@
+package com.fuint.common.dto.ext;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.List;
+
+// 分页响应体
+@Data
+@AllArgsConstructor
+public class PageResult<T> {
+    private Long current;
+    private Long size;
+    private Long total;
+    private List<T> records;
+}

+ 0 - 2
fuintBackend/fuint-application/src/main/java/com/fuint/common/dto/ext/ShopAlertInfo.java

@@ -1,8 +1,6 @@
 package com.fuint.common.dto.ext;
 
 
-import com.fuint.common.entity.Order;
-import com.fuint.common.entity.Shop;
 import com.fuint.repository.model.MtOrder;
 import com.fuint.repository.model.MtStore;
 import lombok.AllArgsConstructor;

+ 21 - 0
fuintBackend/fuint-application/src/main/java/com/fuint/common/dto/ext/ShopAlertRequest.java

@@ -0,0 +1,21 @@
+package com.fuint.common.dto.ext;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class ShopAlertRequest {
+    //    @NotNull(message = "店铺id不能为空")
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    //    @NotBlank(message = "邮箱不能为空")
+//    @Email(message = "邮箱格式不合法")
+    private String mail;
+
+    //    @NotNull(message = "预警值不能为空")
+//    @DecimalMin(value = "0.0", inclusive = false, message = "预警值必须大于0")
+    private BigDecimal threshold;
+}

+ 0 - 2
fuintBackend/fuint-application/src/main/java/com/fuint/common/service/EmailService.java

@@ -3,8 +3,6 @@ package com.fuint.common.service;
 
 
 import com.fuint.common.dto.ext.ShopAlertInfo;
-import com.fuint.common.entity.Order;
-import com.fuint.common.entity.Shop;
 import com.fuint.repository.model.MtOrder;
 import com.fuint.repository.model.MtStore;
 import lombok.RequiredArgsConstructor;

+ 60 - 0
fuintBackend/fuint-application/src/main/java/com/fuint/common/service/ShopAlertService.java

@@ -0,0 +1,60 @@
+package com.fuint.common.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fuint.common.dto.ext.PageResult;
+import com.fuint.common.vo.ShopDetailVO;
+import com.fuint.common.vo.ShopVO;
+import com.fuint.framework.exception.BusinessCheckException;
+import com.fuint.repository.model.MtStore;
+
+import java.math.BigDecimal;
+
+
+/**
+ * @author Survive
+ * @date 2025/3/12
+ * @description TODO 店铺预警相关接口
+ */
+public interface ShopAlertService extends IService<MtStore> {
+    /**
+     * 新增店铺预警信息
+     * @param id
+     * @param mail
+     * @param threshold
+     * @throws BusinessCheckException
+     */
+    void addShopAlert(Long id, String mail, BigDecimal threshold) throws BusinessCheckException;
+
+    /**
+     * 更新店铺预警信息
+     * @param shopId
+     * @param mail
+     * @param threshold
+     * @return
+     */
+    MtStore updateShopAlert(Long shopId, String mail, BigDecimal threshold) throws BusinessCheckException;
+
+
+    /**
+     * 清空预警信息
+     * @param shopId
+     * @return
+     */
+    MtStore clearAlertConfig(Long shopId) throws BusinessCheckException ;
+
+    /**
+     * 详情
+     * @param shopId
+     * @param withOrders
+     */
+    ShopDetailVO getShopDetail(Long shopId, Boolean withOrders) throws BusinessCheckException ;
+
+    /**
+     * 分页查询
+     * @param page
+     * @param size
+     * @param name
+     * @return
+     */
+    PageResult<ShopVO> listShops(Integer page, Integer size, String name) throws BusinessCheckException;
+}

+ 193 - 0
fuintBackend/fuint-application/src/main/java/com/fuint/common/service/impl/ShopAlertServiceImpl.java

@@ -0,0 +1,193 @@
+package com.fuint.common.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fuint.common.dto.ext.PageResult;
+import com.fuint.common.service.ShopAlertService;
+import com.fuint.common.service.TableService;
+import com.fuint.common.util.I18nUtil;
+import com.fuint.common.vo.OrderVO;
+import com.fuint.common.vo.ShopDetailVO;
+import com.fuint.common.vo.ShopVO;
+import com.fuint.framework.exception.BusinessCheckException;
+import com.fuint.repository.mapper.MtOrderMapper;
+import com.fuint.repository.mapper.MtStoreMapper;
+import com.fuint.repository.mapper.MtTableMapper;
+import com.fuint.repository.model.MtOrder;
+import com.fuint.repository.model.MtStore;
+import com.fuint.repository.model.MtTable;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Survive
+ * @date 2025/3/12
+ * @description TODO
+ */
+@Service
+@AllArgsConstructor
+public class ShopAlertServiceImpl extends ServiceImpl<MtStoreMapper, MtStore> implements ShopAlertService {
+
+
+    private MtStoreMapper shopMapper;
+
+    private MtOrderMapper orderMapper;
+
+    @Override
+    @Transactional
+    public void addShopAlert(Long shopId, String mail, BigDecimal threshold) throws BusinessCheckException {
+        // 1. 校验店铺存在性
+        MtStore shop = shopMapper.selectById(shopId);
+        if (shop == null) {
+            throw new BusinessCheckException(I18nUtil.getMessage("storeNonexistent"));
+        }
+        // 2. 更新字段
+        shop.setMail(mail);
+        shop.setThreshold(threshold);
+
+        // 3. 持久化到数据库
+        int rows = shopMapper.updateById(shop);
+    }
+
+    @Override
+    @Transactional
+    public MtStore updateShopAlert(Long id, String mail, BigDecimal threshold) throws BusinessCheckException{
+        // 1. 验证店铺存在性
+        MtStore shop = shopMapper.selectById(id);
+        if (shop == null) {
+            throw new BusinessCheckException(I18nUtil.getMessage("storeNonexistent"));
+        }
+
+        // 2. 数据更新
+        shop.setMail(mail);
+        shop.setThreshold(threshold);
+        shop.setUpdateTime(new Date()); // 更新时间戳
+
+        int rows = shopMapper.updateById(shop);
+        if (rows == 0){
+            throw new BusinessCheckException(I18nUtil.getMessage("updateFail"));
+        }
+        return shop;
+    }
+
+    @Override
+    @Transactional
+    public MtStore clearAlertConfig(Long shopId) throws BusinessCheckException{
+        // 1. 验证店铺存在性
+        MtStore shop = shopMapper.selectById(shopId);
+        if (shop == null) {
+            throw new BusinessCheckException(I18nUtil.getMessage("storeNonexistent"));
+        }
+
+        // 2. 清除预警配置
+        shop.setMail("");          // 清空邮箱
+        shop.setThreshold(BigDecimal.ZERO);  // 重置阈值
+        shop.setUpdateTime(new Date());
+        int rows = shopMapper.updateById(shop);
+        return shop;
+    }
+
+
+    /**
+     * 店铺详情
+     * @param shopId
+     * @param withOrders 否携带当日订单
+     * @return
+     */
+    @Override
+    public ShopDetailVO getShopDetail(Long shopId, Boolean withOrders) throws BusinessCheckException{
+        // 1. 查询基础信息
+        MtStore shop = shopMapper.selectById(shopId);
+        if (shop == null) {
+            throw new BusinessCheckException(I18nUtil.getMessage("storeNonexistent"));
+        }
+
+        // 2. 构建VO对象
+        ShopDetailVO vo = new ShopDetailVO()
+                .setId(shop.getId())
+                .setName(shop.getName())
+                .setMail(shop.getMail())
+                .setThreshold(shop.getThreshold())
+                .setCreateTime(shop.getCreateTime())
+                .setUpdateTime(shop.getUpdateTime());
+
+        // 3. 查询当日订单(按需加载)
+        if (Boolean.TRUE.equals(withOrders)) {
+            List<MtOrder> orders = orderMapper.selectList(
+                    new LambdaQueryWrapper<MtOrder>()
+                            .eq(MtOrder::getStoreId, shopId)
+                            .ge(MtOrder::getCreateTime, LocalDate.now().atStartOfDay())
+            );
+            vo.setOrdersToday(convertToOrderVO(orders));
+        }
+        return vo;
+    }
+
+    /**
+     * 分页查询店铺列表
+     * @param page
+     * @param size
+     * @param name
+     * @return
+     */
+    @Override
+    public PageResult<ShopVO> listShops(Integer page, Integer size, String name) {
+        // 1. 构建分页参数
+        Page<MtStore> pageParam = new Page<>(page, size);
+
+        // 2. 构建查询条件
+        LambdaQueryWrapper<MtStore> wrapper = new LambdaQueryWrapper<>();
+        wrapper.like(StringUtils.hasText(name), MtStore::getName, name)
+                .select(MtStore::getId, MtStore::getName, MtStore::getMail,
+                        MtStore::getContact, MtStore::getPhone,
+                        MtStore::getThreshold, MtStore::getUpdateTime);
+
+        // 3. 执行分页查询
+        Page<MtStore> shopPage = (Page<MtStore>) shopMapper.selectPage(pageParam, wrapper);
+
+        //计算每个店铺的总收益额
+        // 4. 转换VO对象
+        List<ShopVO> vos = shopPage.getRecords().stream()
+                .map(shop -> new ShopVO(
+                        shop.getId(),
+                        shop.getName(),
+                        shop.getMail(),
+                        shop.getPhone(),
+                        shop.getContact(),
+                        shop.getThreshold(),
+                        shop.getUpdateTime()
+                ))
+                .collect(Collectors.toList());
+
+        // 5. 封装分页结果
+        return new PageResult<>(
+                shopPage.getCurrent(),
+                shopPage.getSize(),
+                shopPage.getTotal(),
+                vos
+        );
+    }
+
+
+    /**
+     * 参数转换  MtOrder-》vo
+     * @param orders
+     * @return
+     */
+    private List<OrderVO> convertToOrderVO(List<MtOrder> orders) {
+        return orders.stream()
+                .map(o -> new OrderVO(o.getId(), o.getAmount(), o.getCreateTime()))
+                .collect(Collectors.toList());
+    }
+}

+ 17 - 0
fuintBackend/fuint-application/src/main/java/com/fuint/common/vo/OrderVO.java

@@ -0,0 +1,17 @@
+package com.fuint.common.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+// 订单VO
+@Data
+@AllArgsConstructor
+public class OrderVO {
+    private Long id;
+    private BigDecimal amount;
+    private Date createTime;
+}

+ 23 - 0
fuintBackend/fuint-application/src/main/java/com/fuint/common/vo/ShopDetailVO.java

@@ -0,0 +1,23 @@
+package com.fuint.common.vo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+
+// 详情响应对象
+@Data
+@Accessors(chain = true)
+public class ShopDetailVO {
+    private Long id;
+    private String name;
+    private String mail;
+    private BigDecimal threshold;
+    private Date createTime;
+    private Date updateTime;
+//    当日订单
+    private List<OrderVO> ordersToday;
+}

+ 29 - 0
fuintBackend/fuint-application/src/main/java/com/fuint/common/vo/ShopVO.java

@@ -0,0 +1,29 @@
+package com.fuint.common.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+// 店铺VO对象
+@Data
+@AllArgsConstructor
+public class ShopVO {
+    private Long id;
+    private String name;
+    @ApiModelProperty("店铺负责人")
+    private String contact;
+    @ApiModelProperty("联系电话")
+    private String phone;
+    @ApiModelProperty("收件邮箱")
+    private String mail;
+    @ApiModelProperty("预警阈值")
+    private BigDecimal threshold;
+    @ApiModelProperty("更新时间")
+    private Date updateTime;
+   /* @ApiModelProperty("总收益额")
+    private BigDecimal totalIncome;*/
+}

+ 112 - 0
fuintBackend/fuint-application/src/main/java/com/fuint/module/backendApi/controller/ShopAlertController.java

@@ -0,0 +1,112 @@
+package com.fuint.module.backendApi.controller;
+
+import com.fuint.common.dto.ext.PageResult;
+import com.fuint.common.dto.ext.ShopAlertRequest;
+import com.fuint.common.service.ShopAlertService;
+import com.fuint.common.vo.ShopDetailVO;
+import com.fuint.common.vo.ShopVO;
+import com.fuint.framework.exception.BusinessCheckException;
+import com.fuint.framework.web.BaseController;
+import com.fuint.framework.web.ResponseObject;
+import com.fuint.repository.model.MtStore;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author Survive
+ * @date 2025/3/12
+ * @description TODO
+ */
+@Api(tags="管理端-预警相关接口")
+@RestController
+@AllArgsConstructor
+@RequestMapping("/backendApi/shop-alerts")
+public class ShopAlertController extends BaseController {
+    private ShopAlertService shopService;
+
+    /**
+     * 分页数据展示
+     * @param page
+     * @param size
+     * @param name
+     * @return
+     */
+    @GetMapping(value = "/list")
+    @CrossOrigin
+    @ApiOperation(value = "店铺列表")
+    public PageResult<ShopVO> listShops(
+            @RequestParam(defaultValue = "1") Integer page,
+            @RequestParam(defaultValue = "10") Integer size,
+            @RequestParam(required = false) String name
+    ) throws BusinessCheckException{
+        PageResult<ShopVO> result = shopService.listShops(page, size, name);
+        return result;
+    }
+
+
+    /**
+     * 店铺详情
+     * @param shopId
+     * @param withOrders 否携带当日订单
+     * @return
+     */
+    @ApiOperation(value = "店铺详情")
+    @GetMapping("/{shopId}")
+    @CrossOrigin
+//    @PreAuthorize("@pms.hasPermission('alerts:index')")
+    public ResponseObject getShopDetail(HttpServletRequest request, @PathVariable Long shopId, @RequestParam(required = false) Boolean withOrders  ) throws BusinessCheckException {
+        ShopDetailVO shopDetail = shopService.getShopDetail(shopId, withOrders);
+        return getSuccessResult(shopDetail);
+    }
+
+    /**
+     * 新增预警信息
+     * @param request
+     * @return
+     */
+    @ApiOperation(value = "新增预警")
+    @RequestMapping(value = "/add", method = RequestMethod.POST)
+    @CrossOrigin
+//    @PreAuthorize("@pms.hasPermission('alerts:index')")
+    public ResponseObject createAlert(HttpServletRequest request, @RequestBody ShopAlertRequest alertInfo) throws BusinessCheckException {
+        shopService.addShopAlert(alertInfo.getId(),
+                alertInfo.getMail(),
+                alertInfo.getThreshold());
+        return getSuccessResult(true);
+    }
+
+    /**
+     * 更新预警信息
+     * @param shopId
+     * @param request
+     * @return
+     */
+    @ApiOperation(value = "更新预警")
+    @CrossOrigin
+    @PostMapping("/update/{shopId}")
+    //    @PreAuthorize("@pms.hasPermission('alerts:index')")
+    public ResponseObject updateShopAlert(@PathVariable Long shopId, @RequestBody ShopAlertRequest request) throws BusinessCheckException{
+        MtStore updatedShop = shopService.updateShopAlert(shopId, request.getMail(), request.getThreshold());
+        return getSuccessResult("更新成功",updatedShop);
+    }
+
+    /**
+     * 清除预警信息
+     * @param shopId
+     * @return
+     */
+    @ApiOperation(value = "清除预警配置信息")
+    @CrossOrigin
+    @PostMapping("/clear/{shopId}")
+    //    @PreAuthorize("@pms.hasPermission('alerts:index')")
+    public ResponseObject clearAlertConfig ( @PathVariable Long shopId ) throws BusinessCheckException{
+        MtStore updatedShop = shopService.clearAlertConfig(shopId);
+        return getSuccessResult("预警配置已清除", updatedShop);
+    }
+}