Explorar el Código

等级管理完成一半

Huanyi hace 3 semanas
padre
commit
7214642ea4
Se han modificado 41 ficheros con 1593 adiciones y 18 borrados
  1. 1 0
      ruoyi-common/pom.xml
  2. 7 0
      ruoyi-common/ruoyi-common-bom/pom.xml
  3. 13 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
  4. 33 0
      ruoyi-common/yingpaipay-common-external/pom.xml
  5. 22 0
      ruoyi-common/yingpaipay-common-external/src/main/java/org/dromara/common/external/timor/DateInfo.java
  6. 58 0
      ruoyi-common/yingpaipay-common-external/src/main/java/org/dromara/common/external/timor/TimorClient.java
  7. 14 0
      ruoyi-common/yingpaipay-common-external/src/main/java/org/dromara/common/external/timor/TimorHolidayYear.java
  8. 1 0
      ruoyi-modules/yingpaipay-archieves/src/main/java/org/dromara/archieves/domain/bo/UsrCustomerBo.java
  9. 2 2
      ruoyi-modules/yingpaipay-archieves/src/main/java/org/dromara/archieves/service/impl/UsrCustomerServiceImpl.java
  10. 5 0
      ruoyi-modules/yingpaipay-fulfiller/pom.xml
  11. 47 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfLevelConfigController.java
  12. 48 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfLevelRigthtsController.java
  13. 35 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfViolationController.java
  14. 52 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfComplaintLog.java
  15. 123 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfLevelConfig.java
  16. 50 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfLevelRights.java
  17. 60 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfViolationLog.java
  18. 47 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfComplaintLogBo.java
  19. 10 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfFulfillerBo.java
  20. 127 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfLevelConfigBo.java
  21. 52 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfLevelRightsBo.java
  22. 55 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfViolationLogBo.java
  23. 56 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/vo/FlfComplaintLogVo.java
  24. 158 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/vo/FlfLevelConfigVo.java
  25. 66 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/vo/FlfLevelRightsVo.java
  26. 64 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/vo/FlfViolationLogVo.java
  27. 27 2
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/dubbo/RemoteFulfillerServiceImpl.java
  28. 15 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/mapper/FlfComplaintLogMapper.java
  29. 15 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/mapper/FlfLevelConfigMapper.java
  30. 15 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/mapper/FlfLevelRightsMapper.java
  31. 15 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/mapper/FlfViolationLogMapper.java
  32. 10 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfComplaintLogService.java
  33. 9 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfLevelConfigService.java
  34. 16 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfLevelRightsService.java
  35. 19 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfViolationLogService.java
  36. 22 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfComplaintLogServiceImpl.java
  37. 56 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfFlfLevelRightsServiceImpl.java
  38. 21 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfLevelConfigServiceImpl.java
  39. 41 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfViolationLogServiceImpl.java
  40. 4 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderCreateBo.java
  41. 102 14
      script/sql/business/create.sql

+ 1 - 0
ruoyi-common/pom.xml

@@ -45,6 +45,7 @@
         <module>ruoyi-common-bus</module>
         <module>ruoyi-common-sse</module>
         <module>yingpaipay-common-platform</module>
+        <module>yingpaipay-common-external</module>
     </modules>
 
     <artifactId>ruoyi-common</artifactId>

+ 7 - 0
ruoyi-common/ruoyi-common-bom/pom.xml

@@ -257,6 +257,13 @@
                 <version>${revision}</version>
             </dependency>
 
+            <!-- 第三方API调用 -->
+            <dependency>
+                <groupId>org.dromara</groupId>
+                <artifactId>yingpaipay-common-external</artifactId>
+                <version>${revision}</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 </project>

+ 13 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java

@@ -127,4 +127,17 @@ public interface CacheNames {
      * @Author: Huanyi
      */
     String FLF_FULFILLER_NAME = "flf_fulfiller_name#30d";
+
+    /**
+     * 履约者配置
+     * @Author: Huanyi
+     */
+    String FLF_CONFIG = "flf_config#30d";
+
+    /**
+     * 标签
+     * @Author: Huanyi
+     */
+    String SYS_TAG = "sys_tag#30d";
+
 }

+ 33 - 0
ruoyi-common/yingpaipay-common-external/pom.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.dromara</groupId>
+        <artifactId>ruoyi-common</artifactId>
+        <version>${revision}</version>
+    </parent>
+
+    <artifactId>yingpaipay-common-external</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-http</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-json</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 22 - 0
ruoyi-common/yingpaipay-common-external/src/main/java/org/dromara/common/external/timor/DateInfo.java

@@ -0,0 +1,22 @@
+package org.dromara.common.external.timor;
+
+import lombok.Data;
+
+@Data
+public class DateInfo {
+
+    private Boolean holiday;
+
+    private String name;
+
+    private Integer wage;
+
+    private String date;
+
+    private Integer rest;
+
+    private Boolean after;
+
+    private String target;
+
+}

+ 58 - 0
ruoyi-common/yingpaipay-common-external/src/main/java/org/dromara/common/external/timor/TimorClient.java

@@ -0,0 +1,58 @@
+package org.dromara.common.external.timor;
+
+import cn.hutool.http.HttpException;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.dromara.common.json.utils.JsonUtils;
+
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.Map;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class TimorClient {
+
+    private static final String BASE_URL = "https://timor.tech/api";
+    private static final DateTimeFormatter KEY_FORMATTER = DateTimeFormatter.ofPattern("MM-dd");
+
+    public static boolean isHoliday(Date time) {
+
+        if (time == null) {
+            return false;
+        }
+
+        LocalDate localDate = time.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+        int year = localDate.getYear();
+        String dateKey = localDate.format(KEY_FORMATTER);
+
+        try (HttpResponse response = HttpRequest.get(BASE_URL + "/holiday/year/" + year).execute()) {
+
+            if (response.getStatus() != 200) {
+                throw new HttpException("网络异常 : " + response.getStatus());
+            }
+            TimorHolidayYear result = JsonUtils.parseObject(response.body(), TimorHolidayYear.class);
+
+            if (result == null || result.getCode() != 0) {
+                throw new RuntimeException("请求失败");
+            }
+
+            Map<String, DateInfo> holiday = result.getHoliday();
+
+            DateInfo info = holiday.get(dateKey);
+            if (info != null) {
+                return Boolean.TRUE.equals(info.getHoliday());
+            }
+
+        }
+        return false;
+    }
+
+    public static boolean isNotHoliday(Date time) {
+        return !isHoliday(time);
+    }
+
+}

+ 14 - 0
ruoyi-common/yingpaipay-common-external/src/main/java/org/dromara/common/external/timor/TimorHolidayYear.java

@@ -0,0 +1,14 @@
+package org.dromara.common.external.timor;
+
+import lombok.Data;
+
+import java.util.Map;
+
+@Data
+public class TimorHolidayYear {
+
+    private Integer code;
+
+    private Map<String, DateInfo> holiday;
+
+}

+ 1 - 0
ruoyi-modules/yingpaipay-archieves/src/main/java/org/dromara/archieves/domain/bo/UsrCustomerBo.java

@@ -93,6 +93,7 @@ public class UsrCustomerBo extends BaseEntity {
     /**
      * 来源渠道
      */
+    @NotBlank(message = "所属品牌不能为空", groups = { AddGroup.class })
     private String tenantId;
 
     /**

+ 2 - 2
ruoyi-modules/yingpaipay-archieves/src/main/java/org/dromara/archieves/service/impl/UsrCustomerServiceImpl.java

@@ -78,13 +78,13 @@ public class UsrCustomerServiceImpl implements IUsrCustomerService {
             vo.setTags(queryTagsByTargetId(vo.getId(), TagTargetConstants.CUSTOMER));
             customerIds.add(vo.getId());
         });
-        Map<Long, Integer> petMap = petMapper.selectList(Wrappers.lambdaQuery(UsrPet.class).in(UsrPet::getUserId, customerIds).select(UsrPet::getId, UsrPet::getUserId))
+        Map<Long, Integer> petMap = petMapper.selectList(Wrappers.lambdaQuery(UsrPet.class).in(UsrPet::getUserId, WrapperUtils.convertIds(customerIds)).select(UsrPet::getId, UsrPet::getUserId))
             .stream()
             .collect(Collectors.groupingBy(
                 UsrPet::getUserId,
                 Collectors.summingInt(e -> 1)
             ));
-        Map<Long, Integer> orderMap = remoteSubOrderService.selectByCustomerIds(customerIds).stream()
+        Map<Long, Integer> orderMap = remoteSubOrderService.selectByCustomerIds(WrapperUtils.convertIds(customerIds)).stream()
             .collect(Collectors.groupingBy(
                 RemoteSubOrderVo::getCustomer,
                 Collectors.summingInt(e -> 1)

+ 5 - 0
ruoyi-modules/yingpaipay-fulfiller/pom.xml

@@ -135,6 +135,11 @@
             <scope>compile</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>yingpaipay-common-external</artifactId>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 47 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfLevelConfigController.java

@@ -0,0 +1,47 @@
+package org.dromara.fulfiller.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.fulfiller.domain.bo.FlfLevelConfigBo;
+import org.dromara.fulfiller.domain.vo.FlfLevelConfigVo;
+import org.dromara.fulfiller.service.IFlfLevelConfigService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/levelConfig")
+public class FlfLevelConfigController extends BaseController {
+
+    private final IFlfLevelConfigService flfLevelConfigService;
+
+    @GetMapping("/listAll")
+    public R<List<FlfLevelConfigVo>> listAll() {
+        return R.ok(flfLevelConfigService.listAll());
+    }
+
+    @RepeatSubmit()
+    @PostMapping("/add")
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody FlfLevelConfigBo bo) {
+        return R.ok();
+    }
+
+    @RepeatSubmit()
+    @PutMapping("/edit")
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody FlfLevelConfigBo bo) {
+        return R.ok();
+    }
+
+    @DeleteMapping("/remove")
+    public R<Void> remove(@RequestParam Long id) {
+        return R.ok();
+    }
+
+}

+ 48 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfLevelRigthtsController.java

@@ -0,0 +1,48 @@
+package org.dromara.fulfiller.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.fulfiller.domain.bo.FlfLevelRightsBo;
+import org.dromara.fulfiller.domain.vo.FlfLevelRightsVo;
+import org.dromara.fulfiller.service.IFlfLevelRightsService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/levelRights")
+public class FlfLevelRigthtsController extends BaseController {
+
+    private final IFlfLevelRightsService levelRightsService;
+
+    @GetMapping("/listAll")
+    public R<List<FlfLevelRightsVo>> listAll() {
+        List<FlfLevelRightsVo> list = levelRightsService.listAll();
+        return R.ok(list);
+    }
+
+    @RepeatSubmit()
+    @PostMapping("/add")
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody FlfLevelRightsBo bo) {
+        return toAjax(levelRightsService.insertByBo(bo) != null);
+    }
+
+    @RepeatSubmit()
+    @PutMapping("/edit")
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody FlfLevelRightsBo bo) {
+        return toAjax(levelRightsService.updateByBo(bo) != null);
+    }
+
+    @DeleteMapping("/remove")
+    public R<Void> remove(@RequestParam Long id) {
+        return toAjax(levelRightsService.deleteById(id));
+    }
+
+}

+ 35 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfViolationController.java

@@ -0,0 +1,35 @@
+package org.dromara.fulfiller.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.fulfiller.domain.bo.FlfViolationLogBo;
+import org.dromara.fulfiller.domain.vo.FlfViolationLogVo;
+import org.dromara.fulfiller.service.IFlfViolationLogService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/violation")
+public class FlfViolationController extends BaseController {
+
+    private final IFlfViolationLogService flfViolationLogService;
+
+    @RepeatSubmit()
+    @PostMapping("/add")
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody FlfViolationLogBo bo) {
+        return toAjax(flfViolationLogService.insertByBo(bo));
+    }
+
+    @GetMapping("/pageByFulfiller")
+    public TableDataInfo<FlfViolationLogVo> pageByFulfiller(@RequestParam Long fulfillerId, PageQuery pageQuery) {
+        return flfViolationLogService.pageByFulfiller(fulfillerId, pageQuery);
+    }
+
+}

+ 52 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfComplaintLog.java

@@ -0,0 +1,52 @@
+package org.dromara.fulfiller.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 投诉信息对象 flf_complaint_log
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("flf_complaint_log")
+public class FlfComplaintLog extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 履约者
+     */
+    private Long fulfiller;
+
+    /**
+     * 关联订单
+     */
+    private Long orderId;
+
+    /**
+     * 投诉原因
+     */
+    private String reason;
+
+    /**
+     * 删除标志(0代表存在 1代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+
+}

+ 123 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfLevelConfig.java

@@ -0,0 +1,123 @@
+package org.dromara.fulfiller.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+
+import java.io.Serial;
+
+/**
+ * 等级配置信息对象 flf_level_config
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("flf_level_config")
+public class FlfLevelConfig extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 等级数值
+     */
+    private Integer lvNo;
+
+    /**
+     * 等级名称
+     */
+    private String name;
+
+    /**
+     * 等级图标
+     */
+    private Long icon;
+
+    /**
+     * 背景图片
+     */
+    private Long background;
+
+    /**
+     * 节假日加成
+     */
+    private Integer holidayBonus;
+
+    /**
+     * 完成单量
+     */
+    private Integer upgradeCompleteOrderQuality;
+
+    /**
+     * 上门准时率
+     */
+    private Integer upgradeOntimeRate;
+
+    /**
+     * 投诉率
+     */
+    private Integer upgradeComplaintRate;
+
+    /**
+     * 违规次数
+     */
+    private Integer upgradeViolationsCount;
+
+    /**
+     * 积分升级门槛
+     */
+    private Integer upgradePoints;
+
+    /**
+     * 积分降级门槛
+     */
+    private Integer degradePoints;
+
+    /**
+     * 自然月内上门准时率低于%
+     */
+    private Integer degradeOntimeRate;
+
+    /**
+     * 自然月内上门准时率低于a%,自动扣罚积分
+     */
+    private Integer degradeOntimeRateScore;
+
+    /**
+     * 自然月内完成订单小于等于
+     */
+    private Integer degradeCompleteOrderQuality;
+
+    /**
+     * 自然月内完成订单为y,自动扣罚积分
+     */
+    private Integer degradeCompleteOrderQualityScore;
+
+    /**
+     * 违规一次,人工扣罚
+     */
+    private Integer degradeViolationsScore;
+
+    /**
+     * 自然月内投诉率达到%
+     */
+    private Integer degradeComplaintCount;
+
+    /**
+     * 自然月内投诉率达到a%,自动扣罚积分
+     */
+    private Integer degradeComplaintCountScore;
+
+
+}

+ 50 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfLevelRights.java

@@ -0,0 +1,50 @@
+package org.dromara.fulfiller.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 等级权益信息对象 flf_level_rights
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("flf_level_rights")
+public class FlfLevelRights extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 图标
+     */
+    private Long icon;
+
+    /**
+     * 状态
+     */
+    private Boolean status;
+
+    /**
+     * 权益说明
+     */
+    private String statement;
+
+}

+ 60 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfViolationLog.java

@@ -0,0 +1,60 @@
+package org.dromara.fulfiller.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 违规信息对象 flf_violation_log
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("flf_violation_log")
+public class FlfViolationLog extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 履约者
+     */
+    private Long fulfiller;
+
+    /**
+     * 违规次数
+     */
+    private Integer count;
+
+    /**
+     * 违规时间
+     */
+    private Date violationTime;
+
+    /**
+     * 原因
+     */
+    private String reason;
+
+    /**
+     * 删除标志(0代表存在 1代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+
+}

+ 47 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfComplaintLogBo.java

@@ -0,0 +1,47 @@
+package org.dromara.fulfiller.domain.bo;
+
+import org.dromara.fulfiller.domain.FlfComplaintLog;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 投诉信息业务对象 flf_complaint_log
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = FlfComplaintLog.class, reverseConvertGenerate = false)
+public class FlfComplaintLogBo extends BaseEntity {
+
+    /**
+     * 序号
+     */
+    @NotNull(message = "序号不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 履约者
+     */
+    @NotNull(message = "履约者不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long fulfiller;
+
+    /**
+     * 关联订单
+     */
+    @NotNull(message = "关联订单不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long orderId;
+
+    /**
+     * 投诉原因
+     */
+    private String reason;
+
+
+}

+ 10 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfFulfillerBo.java

@@ -127,4 +127,14 @@ public class FlfFulfillerBo extends BaseEntity {
      */
     private List<Long> tagIds;
 
+    /**
+     * 身份证正面(OSS ID)
+     */
+    private Long idCardFront;
+
+    /**
+     * 身份证背面(OSS ID)
+     */
+    private Long idCardBack;
+
 }

+ 127 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfLevelConfigBo.java

@@ -0,0 +1,127 @@
+package org.dromara.fulfiller.domain.bo;
+
+import org.dromara.fulfiller.domain.FlfLevelConfig;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+
+import java.util.List;
+
+/**
+ * 等级配置信息业务对象 flf_level_config
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = FlfLevelConfig.class, reverseConvertGenerate = false)
+public class FlfLevelConfigBo extends BaseEntity {
+
+    /**
+     * 序号
+     */
+    @NotNull(message = "序号不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 等级数值
+     */
+    @NotNull(message = "等级数值不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Integer lvNo;
+
+    /**
+     * 等级名称
+     */
+    @NotBlank(message = "等级名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String name;
+
+    /**
+     * 等级图标
+     */
+    private Long icon;
+
+    /**
+     * 背景图片
+     */
+    private Long background;
+
+    /**
+     * 节假日加成
+     */
+    private Integer holidayBonus;
+
+    /**
+     * 完成单量
+     */
+    private Integer upgradeCompleteOrderQuality;
+
+    /**
+     * 上门准时率
+     */
+    private Integer upgradeOntimeRate;
+
+    /**
+     * 投诉率
+     */
+    private Integer upgradeComplaintRate;
+
+    /**
+     * 违规次数
+     */
+    private Integer upgradeViolationsCount;
+
+    /**
+     * 积分升级门槛
+     */
+    private Integer upgradePoints;
+
+    /**
+     * 积分降级门槛
+     */
+    private Integer degradePoints;
+
+    /**
+     * 自然月内上门准时率低于%
+     */
+    private Integer degradeOntimeRate;
+
+    /**
+     * 自然月内上门准时率低于a%,自动扣罚积分
+     */
+    private Integer degradeOntimeRateScore;
+
+    /**
+     * 自然月内完成订单小于等于
+     */
+    private Integer degradeCompleteOrderQuality;
+
+    /**
+     * 自然月内完成订单为y,自动扣罚积分
+     */
+    private Integer degradeCompleteOrderQualityScore;
+
+    /**
+     * 违规一次,人工扣罚
+     */
+    private Integer degradeViolationsScore;
+
+    /**
+     * 自然月内投诉率达到%
+     */
+    private Integer degradeComplaintCount;
+
+    /**
+     * 自然月内投诉率达到a%,自动扣罚积分
+     */
+    private Integer degradeComplaintCountScore;
+
+    private List<Long> rights;
+
+}

+ 52 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfLevelRightsBo.java

@@ -0,0 +1,52 @@
+package org.dromara.fulfiller.domain.bo;
+
+import org.dromara.fulfiller.domain.FlfLevelRights;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 等级权益信息业务对象 flf_level_rights
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = FlfLevelRights.class, reverseConvertGenerate = false)
+public class FlfLevelRightsBo extends BaseEntity {
+
+    /**
+     * 序号
+     */
+    @NotNull(message = "序号不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 名称
+     */
+    @NotBlank(message = "名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String name;
+
+    /**
+     * 图标
+     */
+    private Long icon;
+
+    /**
+     * 状态
+     */
+    @NotNull(message = "状态不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Boolean status;
+
+    /**
+     * 权益说明
+     */
+    private String statement;
+
+
+}

+ 55 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfViolationLogBo.java

@@ -0,0 +1,55 @@
+package org.dromara.fulfiller.domain.bo;
+
+import org.dromara.fulfiller.domain.FlfViolationLog;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 违规信息业务对象 flf_violation_log
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = FlfViolationLog.class, reverseConvertGenerate = false)
+public class FlfViolationLogBo extends BaseEntity {
+
+    /**
+     * 序号
+     */
+    @NotNull(message = "序号不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 履约者
+     */
+    @NotNull(message = "履约者不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long fulfiller;
+
+    /**
+     * 违规次数
+     */
+    @NotNull(message = "违规次数不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Integer count;
+
+    /**
+     * 违规时间
+     */
+    @NotNull(message = "违规时间不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Date violationTime;
+
+    /**
+     * 原因
+     */
+    private String reason;
+
+
+}

+ 56 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/vo/FlfComplaintLogVo.java

@@ -0,0 +1,56 @@
+package org.dromara.fulfiller.domain.vo;
+
+import org.dromara.fulfiller.domain.FlfComplaintLog;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 投诉信息视图对象 flf_complaint_log
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = FlfComplaintLog.class)
+public class FlfComplaintLogVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @ExcelProperty(value = "序号")
+    private Long id;
+
+    /**
+     * 履约者
+     */
+    @ExcelProperty(value = "履约者")
+    private Long fulfiller;
+
+    /**
+     * 关联订单
+     */
+    @ExcelProperty(value = "关联订单")
+    private Long orderId;
+
+    /**
+     * 投诉原因
+     */
+    @ExcelProperty(value = "投诉原因")
+    private String reason;
+
+
+}

+ 158 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/vo/FlfLevelConfigVo.java

@@ -0,0 +1,158 @@
+package org.dromara.fulfiller.domain.vo;
+
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.fulfiller.domain.FlfLevelConfig;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 等级配置信息视图对象 flf_level_config
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = FlfLevelConfig.class)
+public class FlfLevelConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @ExcelProperty(value = "序号")
+    private Long id;
+
+    /**
+     * 等级数值
+     */
+    @ExcelProperty(value = "等级数值")
+    private Integer lvNo;
+
+    /**
+     * 等级名称
+     */
+    @ExcelProperty(value = "等级名称")
+    private String name;
+
+    /**
+     * 等级图标
+     */
+    @ExcelProperty(value = "等级图标")
+    private Long icon;
+
+    /**
+     * 等级图标Url
+     */
+    @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "icon")
+    private String iconUrl;
+    /**
+     * 背景图片
+     */
+    @ExcelProperty(value = "背景图片")
+    private Long background;
+
+    /**
+     * 背景图片Url
+     */
+    @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "background")
+    private String backgroundUrl;
+    /**
+     * 节假日加成
+     */
+    @ExcelProperty(value = "节假日加成")
+    private Integer holidayBonus;
+
+    /**
+     * 完成单量
+     */
+    @ExcelProperty(value = "完成单量")
+    private Integer upgradeCompleteOrderQuality;
+
+    /**
+     * 上门准时率
+     */
+    @ExcelProperty(value = "上门准时率")
+    private Integer upgradeOntimeRate;
+
+    /**
+     * 投诉率
+     */
+    @ExcelProperty(value = "投诉率")
+    private Integer upgradeComplaintRate;
+
+    /**
+     * 违规次数
+     */
+    @ExcelProperty(value = "违规次数")
+    private Integer upgradeViolationsCount;
+
+    /**
+     * 积分升级门槛
+     */
+    @ExcelProperty(value = "积分升级门槛")
+    private Integer upgradePoints;
+
+    /**
+     * 积分降级门槛
+     */
+    @ExcelProperty(value = "积分降级门槛")
+    private Integer degradePoints;
+
+    /**
+     * 自然月内上门准时率低于%
+     */
+    @ExcelProperty(value = "自然月内上门准时率低于%")
+    private Integer degradeOntimeRate;
+
+    /**
+     * 自然月内上门准时率低于a%,自动扣罚积分
+     */
+    @ExcelProperty(value = "自然月内上门准时率低于a%,自动扣罚积分")
+    private Integer degradeOntimeRateScore;
+
+    /**
+     * 自然月内完成订单小于等于
+     */
+    @ExcelProperty(value = "自然月内完成订单小于等于")
+    private Integer degradeCompleteOrderQuality;
+
+    /**
+     * 自然月内完成订单为y,自动扣罚积分
+     */
+    @ExcelProperty(value = "自然月内完成订单为y,自动扣罚积分")
+    private Integer degradeCompleteOrderQualityScore;
+
+    /**
+     * 违规一次,人工扣罚
+     */
+    @ExcelProperty(value = "违规一次,人工扣罚")
+    private Integer degradeViolationsScore;
+
+    /**
+     * 自然月内投诉率达到%
+     */
+    @ExcelProperty(value = "自然月内投诉率达到%")
+    private Integer degradeComplaintCount;
+
+    /**
+     * 自然月内投诉率达到a%,自动扣罚积分
+     */
+    @ExcelProperty(value = "自然月内投诉率达到a%,自动扣罚积分")
+    private Integer degradeComplaintCountScore;
+
+
+}

+ 66 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/vo/FlfLevelRightsVo.java

@@ -0,0 +1,66 @@
+package org.dromara.fulfiller.domain.vo;
+
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.fulfiller.domain.FlfLevelRights;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 等级权益信息视图对象 flf_level_rights
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = FlfLevelRights.class)
+public class FlfLevelRightsVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @ExcelProperty(value = "序号")
+    private Long id;
+
+    /**
+     * 名称
+     */
+    @ExcelProperty(value = "名称")
+    private String name;
+
+    /**
+     * 图标
+     */
+    @ExcelProperty(value = "图标")
+    @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "icon")
+    private String iconUrl;
+    private Long icon;
+
+    /**
+     * 状态
+     */
+    @ExcelProperty(value = "状态")
+    private Boolean status;
+
+    /**
+     * 权益说明
+     */
+    @ExcelProperty(value = "权益说明")
+    private String statement;
+
+
+}

+ 64 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/vo/FlfViolationLogVo.java

@@ -0,0 +1,64 @@
+package org.dromara.fulfiller.domain.vo;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.fulfiller.domain.FlfViolationLog;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 违规信息视图对象 flf_violation_log
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = FlfViolationLog.class)
+public class FlfViolationLogVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 序号
+     */
+    @ExcelProperty(value = "序号")
+    private Long id;
+
+    /**
+     * 履约者
+     */
+    @ExcelProperty(value = "履约者")
+    private Long fulfiller;
+
+    /**
+     * 违规次数
+     */
+    @ExcelProperty(value = "违规次数")
+    private Integer count;
+
+    /**
+     * 违规时间
+     */
+    @ExcelProperty(value = "违规时间")
+    private Date violationTime;
+
+    /**
+     * 原因
+     */
+    @ExcelProperty(value = "原因")
+    private String reason;
+
+
+}

+ 27 - 2
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/dubbo/RemoteFulfillerServiceImpl.java

@@ -5,8 +5,8 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.common.core.constant.CacheNames;
-import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.exception.user.UserException;
+import org.dromara.common.external.timor.TimorClient;
 import org.dromara.common.tenant.helper.TenantHelper;
 import org.dromara.fulfiller.api.RemoteFulfillerService;
 import org.dromara.fulfiller.api.domain.vo.RemoteFulfillerVo;
@@ -14,10 +14,13 @@ import org.dromara.fulfiller.api.model.FulfillerLoginUser;
 import org.dromara.fulfiller.constants.FlfActionTypeConstant;
 import org.dromara.fulfiller.domain.FlfBalanceLog;
 import org.dromara.fulfiller.domain.FlfFulfiller;
+import org.dromara.fulfiller.domain.FlfPointsLog;
 import org.dromara.fulfiller.enums.FlfBalanceBizTypeEnum;
 import org.dromara.fulfiller.enums.FlfFulfillerStatusEnum;
+import org.dromara.fulfiller.enums.FlfPointsBizTypeEnum;
 import org.dromara.fulfiller.mapper.FlfBalanceLogMapper;
 import org.dromara.fulfiller.mapper.FlfFulfillerMapper;
+import org.dromara.fulfiller.mapper.FlfPointsLogMapper;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
@@ -39,6 +42,7 @@ public class RemoteFulfillerServiceImpl implements RemoteFulfillerService {
 
     private final FlfFulfillerMapper fulfillerMapper;
     private final FlfBalanceLogMapper balanceLogMapper;
+    private final FlfPointsLogMapper pointsLogMapper;
 
     @Override
     public FulfillerLoginUser getFulfillerByPhone(String phone) throws UserException {
@@ -105,6 +109,13 @@ public class RemoteFulfillerServiceImpl implements RemoteFulfillerService {
         FlfFulfiller flfFulfiller = fulfillerMapper.selectById(fulfiller);
         flfFulfiller.setBalance(flfFulfiller.getBalance() + price);
 
+        // FIXME 计算实际积分数
+        int multiple = 1;
+        if (TimorClient.isHoliday(new Date())) {}
+        int points = Math.toIntExact(price) / 100 * multiple;
+
+        flfFulfiller.setPoints(flfFulfiller.getPoints() + points);
+
         boolean flag = fulfillerMapper.updateById(flfFulfiller) == 0;
         if (flag) {
             throw new RuntimeException("新增余额失败");
@@ -121,7 +132,21 @@ public class RemoteFulfillerServiceImpl implements RemoteFulfillerService {
         balanceLog.setSubOrderId(orderId);
         boolean balanceFlag = balanceLogMapper.insert(balanceLog) == 0;
         if (balanceFlag) {
-            throw new RuntimeException("记录日志失败");
+            throw new RuntimeException("记录余额日志失败");
+        }
+
+        FlfPointsLog pointsLog = new FlfPointsLog();
+        pointsLog.setFulfillerId(fulfiller);
+        pointsLog.setType(FlfActionTypeConstant.ADD);
+        pointsLog.setBizType(FlfPointsBizTypeEnum.ORDER_FINISH.getValue());
+        pointsLog.setAmount(points);
+        pointsLog.setPointsAfter(flfFulfiller.getPoints());
+        pointsLog.setReason("完成订单 " + orderCode);
+        pointsLog.setOperatorId(fulfiller);
+        pointsLog.setSubOrderId(orderId);
+        boolean pointsFlag = pointsLogMapper.insert(pointsLog) == 0;
+        if (pointsFlag) {
+            throw new RuntimeException("记录积分日志失败");
         }
 
         return true;

+ 15 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/mapper/FlfComplaintLogMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.fulfiller.mapper;
+
+import org.dromara.fulfiller.domain.FlfComplaintLog;
+import org.dromara.fulfiller.domain.vo.FlfComplaintLogVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 投诉信息Mapper接口
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+public interface FlfComplaintLogMapper extends BaseMapperPlus<FlfComplaintLog, FlfComplaintLogVo> {
+
+}

+ 15 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/mapper/FlfLevelConfigMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.fulfiller.mapper;
+
+import org.dromara.fulfiller.domain.FlfLevelConfig;
+import org.dromara.fulfiller.domain.vo.FlfLevelConfigVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 等级配置信息Mapper接口
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+public interface FlfLevelConfigMapper extends BaseMapperPlus<FlfLevelConfig, FlfLevelConfigVo> {
+
+}

+ 15 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/mapper/FlfLevelRightsMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.fulfiller.mapper;
+
+import org.dromara.fulfiller.domain.FlfLevelRights;
+import org.dromara.fulfiller.domain.vo.FlfLevelRightsVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 等级权益信息Mapper接口
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+public interface FlfLevelRightsMapper extends BaseMapperPlus<FlfLevelRights, FlfLevelRightsVo> {
+
+}

+ 15 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/mapper/FlfViolationLogMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.fulfiller.mapper;
+
+import org.dromara.fulfiller.domain.FlfViolationLog;
+import org.dromara.fulfiller.domain.vo.FlfViolationLogVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 违规信息Mapper接口
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+public interface FlfViolationLogMapper extends BaseMapperPlus<FlfViolationLog, FlfViolationLogVo> {
+
+}

+ 10 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfComplaintLogService.java

@@ -0,0 +1,10 @@
+package org.dromara.fulfiller.service;
+
+/**
+ * 投诉信息Service接口
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+public interface IFlfComplaintLogService {
+}

+ 9 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfLevelConfigService.java

@@ -0,0 +1,9 @@
+package org.dromara.fulfiller.service;
+
+import org.dromara.fulfiller.domain.vo.FlfLevelConfigVo;
+
+import java.util.List;
+
+public interface IFlfLevelConfigService {
+    List<FlfLevelConfigVo> listAll();
+}

+ 16 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfLevelRightsService.java

@@ -0,0 +1,16 @@
+package org.dromara.fulfiller.service;
+
+import org.dromara.fulfiller.domain.bo.FlfLevelRightsBo;
+import org.dromara.fulfiller.domain.vo.FlfLevelRightsVo;
+
+import java.util.List;
+
+public interface IFlfLevelRightsService {
+    List<FlfLevelRightsVo> listAll();
+
+    FlfLevelRightsVo insertByBo(FlfLevelRightsBo bo);
+
+    FlfLevelRightsVo updateByBo(FlfLevelRightsBo bo);
+
+    boolean deleteById(Long id);
+}

+ 19 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfViolationLogService.java

@@ -0,0 +1,19 @@
+package org.dromara.fulfiller.service;
+
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.fulfiller.domain.bo.FlfViolationLogBo;
+import org.dromara.fulfiller.domain.vo.FlfViolationLogVo;
+
+/**
+ * 违规信息Service接口
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+public interface IFlfViolationLogService {
+
+    boolean insertByBo(FlfViolationLogBo bo);
+
+    TableDataInfo<FlfViolationLogVo> pageByFulfiller(Long fulfillerId, PageQuery pageQuery);
+}

+ 22 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfComplaintLogServiceImpl.java

@@ -0,0 +1,22 @@
+package org.dromara.fulfiller.service.impl;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.fulfiller.mapper.FlfComplaintLogMapper;
+import org.dromara.fulfiller.service.IFlfComplaintLogService;
+
+/**
+ * 投诉信息Service业务层处理
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class FlfComplaintLogServiceImpl implements IFlfComplaintLogService {
+
+    private final FlfComplaintLogMapper baseMapper;
+
+}

+ 56 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfFlfLevelRightsServiceImpl.java

@@ -0,0 +1,56 @@
+package org.dromara.fulfiller.service.impl;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.fulfiller.domain.FlfLevelRights;
+import org.dromara.fulfiller.domain.bo.FlfLevelRightsBo;
+import org.dromara.fulfiller.domain.vo.FlfLevelRightsVo;
+import org.dromara.fulfiller.mapper.FlfLevelRightsMapper;
+import org.dromara.fulfiller.service.IFlfLevelRightsService;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class FlfFlfLevelRightsServiceImpl implements IFlfLevelRightsService {
+
+    private final FlfLevelRightsMapper baseMapper;
+
+    @Cacheable(cacheNames = CacheNames.FLF_CONFIG, key = "'level_right'")
+    @Override
+    public List<FlfLevelRightsVo> listAll() {
+        return baseMapper.selectVoList();
+    }
+
+    @CacheEvict(cacheNames = CacheNames.FLF_CONFIG, key = "'level_right'")
+    @Override
+    public FlfLevelRightsVo insertByBo(FlfLevelRightsBo bo) {
+        FlfLevelRights entity = MapstructUtils.convert(bo, FlfLevelRights.class);
+        boolean flag = baseMapper.insert(entity) == 0;
+        if (flag) {
+            throw new RuntimeException("新增失败");
+        }
+        return baseMapper.selectVoById(entity.getId());
+    }
+
+    @CacheEvict(cacheNames = CacheNames.FLF_CONFIG, key = "'level_right'")
+    @Override
+    public FlfLevelRightsVo updateByBo(FlfLevelRightsBo bo) {
+        FlfLevelRights entity = MapstructUtils.convert(bo, FlfLevelRights.class);
+        boolean flag = baseMapper.updateById(entity) == 0;
+        if (flag) {
+            throw new RuntimeException("修改失败");
+        }
+        return baseMapper.selectVoById(entity.getId());
+    }
+
+    @CacheEvict(cacheNames = CacheNames.FLF_CONFIG, key = "'level_right'")
+    @Override
+    public boolean deleteById(Long id) {
+        return baseMapper.deleteById(id) > 0;
+    }
+}

+ 21 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfLevelConfigServiceImpl.java

@@ -0,0 +1,21 @@
+package org.dromara.fulfiller.service.impl;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.fulfiller.domain.vo.FlfLevelConfigVo;
+import org.dromara.fulfiller.mapper.FlfLevelConfigMapper;
+import org.dromara.fulfiller.service.IFlfLevelConfigService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class FlfLevelConfigServiceImpl implements IFlfLevelConfigService {
+
+    private final FlfLevelConfigMapper baseMapper;
+
+    @Override
+    public List<FlfLevelConfigVo> listAll() {
+        return List.of();
+    }
+}

+ 41 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfViolationLogServiceImpl.java

@@ -0,0 +1,41 @@
+package org.dromara.fulfiller.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.fulfiller.domain.FlfViolationLog;
+import org.dromara.fulfiller.domain.bo.FlfViolationLogBo;
+import org.dromara.fulfiller.domain.vo.FlfViolationLogVo;
+import org.springframework.stereotype.Service;
+import org.dromara.fulfiller.mapper.FlfViolationLogMapper;
+import org.dromara.fulfiller.service.IFlfViolationLogService;
+
+/**
+ * 违规信息Service业务层处理
+ *
+ * @author Huanyi
+ * @date 2026-03-18
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class FlfViolationLogServiceImpl implements IFlfViolationLogService {
+
+    private final FlfViolationLogMapper baseMapper;
+
+    @Override
+    public boolean insertByBo(FlfViolationLogBo bo) {
+        FlfViolationLog entity = MapstructUtils.convert(bo, FlfViolationLog.class);
+        return baseMapper.insert(entity) > 0;
+    }
+
+    @Override
+    public TableDataInfo<FlfViolationLogVo> pageByFulfiller(Long fulfillerId, PageQuery pageQuery) {
+        IPage<FlfViolationLogVo> page = baseMapper.selectVoPage(pageQuery.build(), Wrappers.lambdaQuery(FlfViolationLog.class).eq(FlfViolationLog::getFulfiller, fulfillerId).orderByDesc(FlfViolationLog::getId));
+        return TableDataInfo.build(page);
+    }
+}

+ 4 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderCreateBo.java

@@ -1,5 +1,6 @@
 package org.dromara.order.domain.bo;
 
+import jakarta.validation.constraints.NotEmpty;
 import lombok.Data;
 
 import java.util.Date;
@@ -30,6 +31,7 @@ public class SysSubOrderCreateBo {
     /**
      * 起始服务时间(仅服务单有)
      */
+    @NotEmpty(message = "必须选择服务时间")
     private Date serviceTime;
 
     /**
@@ -40,11 +42,13 @@ public class SysSubOrderCreateBo {
     /**
      * 起点地址编号(仅接送单有)
      */
+    @NotEmpty(message = "必须选择起点或者服务地点")
     private String fromCode;
 
     /**
      * 起点详细地址(仅接送单有)
      */
+    @NotEmpty(message = "必须输入起点或者服务地点的详细地址")
     private String fromAddress;
 
     /**

+ 102 - 14
script/sql/business/create.sql

@@ -225,18 +225,106 @@ CREATE TABLE `pet_system`.`sys_sub_order_log`
 
 CREATE TABLE `pet_system`.`flf_anamaly`
 (
-    `id`            bigint PRIMARY KEY NOT NULL COMMENT '序号',
-    `fulfiller`     bigint             NOT NULL COMMENT '履约者',
-    `order_id`      bigint             NOT NULL COMMENT '关联订单',
-    `type`          char(1)            NOT NULL COMMENT '异常类型',
-    `content`       text               NOT NULL COMMENT '上报内容',
-    `photos`        varchar(512)       COMMENT '上报图片',
-    `status`        tinyint            NOT NULL DEFAULT 0 COMMENT '审核状态',
-    `tenant_id`     varchar(20)        NOT NULL COMMENT '租户编号',
-    `del_flag`      char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
-    `create_dept`   bigint(20) COMMENT '创建部门',
-    `create_by`     bigint(20) COMMENT '创建者',
-    `create_time`   datetime COMMENT '创建时间',
-    `update_by`     bigint(20) COMMENT '更新者',
-    `update_time`   datetime COMMENT '更新时间'
+    `id`          bigint PRIMARY KEY NOT NULL COMMENT '序号',
+    `fulfiller`   bigint             NOT NULL COMMENT '履约者',
+    `order_id`    bigint             NOT NULL COMMENT '关联订单',
+    `type`        char(1)            NOT NULL COMMENT '异常类型',
+    `content`     text               NOT NULL COMMENT '上报内容',
+    `photos`      varchar(512) COMMENT '上报图片',
+    `status`      tinyint            NOT NULL DEFAULT 0 COMMENT '审核状态',
+    `tenant_id`   varchar(20)        NOT NULL COMMENT '租户编号',
+    `del_flag`    char(1)                     DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
+    `create_dept` bigint(20) COMMENT '创建部门',
+    `create_by`   bigint(20) COMMENT '创建者',
+    `create_time` datetime COMMENT '创建时间',
+    `update_by`   bigint(20) COMMENT '更新者',
+    `update_time` datetime COMMENT '更新时间'
 ) ENGINE = innoDB COMMENT = '异常信息表';
+
+# 2026/03/18
+CREATE TABLE `pet_system`.`flf_complaint_log`
+(
+    `id`          bigint PRIMARY KEY NOT NULL COMMENT '序号',
+    `fulfiller`   bigint             NOT NULL COMMENT '履约者',
+    `order_id`    bigint             NOT NULL COMMENT '关联订单',
+    `reason`      varchar(512) COMMENT '投诉原因',
+    `tenant_id`   varchar(20)        NOT NULL COMMENT '租户编号',
+    `del_flag`    char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
+    `create_dept` bigint(20) COMMENT '创建部门',
+    `create_by`   bigint(20) COMMENT '创建者',
+    `create_time` datetime COMMENT '创建时间',
+    `update_by`   bigint(20) COMMENT '更新者',
+    `update_time` datetime COMMENT '更新时间'
+) ENGINE = innoDB COMMENT = '投诉信息表';
+
+CREATE TABLE `pet_system`.`flf_violation_log`
+(
+    `id`             bigint PRIMARY KEY NOT NULL COMMENT '序号',
+    `fulfiller`      bigint             NOT NULL COMMENT '履约者',
+    `count`          int                NOT NULL COMMENT '违规次数',
+    `violation_time` datetime           NOT NULL COMMENT '违规时间',
+    `reason`         varchar(512) COMMENT '原因',
+    `tenant_id`      varchar(20)        NOT NULL COMMENT '租户编号',
+    `del_flag`       char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
+    `create_dept`    bigint(20) COMMENT '创建部门',
+    `create_by`      bigint(20) COMMENT '创建者',
+    `create_time`    datetime COMMENT '创建时间',
+    `update_by`      bigint(20) COMMENT '更新者',
+    `update_time`    datetime COMMENT '更新时间'
+) ENGINE = innoDB COMMENT = '违规信息表';
+
+CREATE TABLE `pet_system`.`flf_level_rights`
+(
+    `id`          bigint PRIMARY KEY   NOT NULL COMMENT '序号',
+    `name`        varchar(64)          NOT NULL COMMENT '名称',
+    `icon`        bigint COMMENT '图标',
+    `status`      boolean DEFAULT true NOT NULL COMMENT '状态',
+    `statement`   varchar(255) COMMENT '权益说明',
+    `create_dept` bigint(20) COMMENT '创建部门',
+    `create_by`   bigint(20) COMMENT '创建者',
+    `create_time` datetime COMMENT '创建时间',
+    `update_by`   bigint(20) COMMENT '更新者',
+    `update_time` datetime COMMENT '更新时间'
+) ENGINE = innoDB COMMENT = '等级权益信息表';
+
+CREATE TABLE `pet_system`.`flf_level_config`
+(
+    `id`                                   bigint PRIMARY KEY NOT NULL COMMENT '序号',
+    `lv_no`                                int                NOT NULL COMMENT '等级数值',
+    `name`                                 varchar(64)        NOT NULL COMMENT '等级名称',
+    `icon`                                 bigint COMMENT '等级图标',
+    `background`                           bigint COMMENT '背景图片',
+    `holiday_bonus`                        int                NOT NULL DEFAULT 100 COMMENT '节假日加成',
+
+    # 升级要求
+    `upgrade_complete_order_quality`       int                NOT NULL DEFAULT 1 COMMENT '完成单量',
+    `upgrade_ontime_rate`                  int                NOT NULL DEFAULT 0 COMMENT '上门准时率',
+    `upgrade_complaint_rate`               int                NOT NULL DEFAULT 0 COMMENT '投诉率',
+    `upgrade_violations_count`             int                NOT NULL DEFAULT 0 COMMENT '违规次数',
+    `upgrade_points`                       int                NOT NULL COMMENT '积分升级门槛',
+
+    # 降级要求
+    `degrade_points`                       int                NOT NULL COMMENT '积分降级门槛',
+
+    # 扣分配置
+    `degrade_ontime_rate`                  int                NOT NULL DEFAULT 0 COMMENT '自然月内上门准时率低于%',
+    `degrade_ontime_rate_score`            int                NOT NULL DEFAULT 0 COMMENT '自然月内上门准时率低于a%,自动扣罚积分',
+    `degrade_complete_order_quality`       int                NOT NULL DEFAULT 0 COMMENT '自然月内完成订单小于等于',
+    `degrade_complete_order_quality_score` int                NOT NULL DEFAULT 0 COMMENT '自然月内完成订单为y,自动扣罚积分',
+    `degrade_violations_score`             int                NOT NULL DEFAULT 0 COMMENT '违规一次,人工扣罚',
+    `degrade_complaint_count`              int                NOT NULL DEFAULT 0 COMMENT '自然月内投诉率达到%',
+    `degrade_complaint_count_score`        int                NOT NULL DEFAULT 0 COMMENT '自然月内投诉率达到a%,自动扣罚积分',
+
+    `create_dept`                          bigint(20) COMMENT '创建部门',
+    `create_by`                            bigint(20) COMMENT '创建者',
+    `create_time`                          datetime COMMENT '创建时间',
+    `update_by`                            bigint(20) COMMENT '更新者',
+    `update_time`                          datetime COMMENT '更新时间'
+) ENGINE = innoDB COMMENT = '等级配置信息表';
+
+CREATE TABLE `pet_system`.`flf_level_config_rights`
+(
+    `config_id`    bigint    NOT NULL COMMENT '配置ID',
+    `rights_id`    bigint    NOT NULL COMMENT '权益ID',
+    PRIMARY KEY (`config_id`, `rights_id`)
+) ENGINE = innoDB COMMENT = '等级配置权益关联表';