Huanyi 4 dienas atpakaļ
vecāks
revīzija
266622ef45
35 mainītis faili ar 649 papildinājumiem un 15 dzēšanām
  1. 8 0
      ruoyi-api/yingpaipay-api-service/src/main/java/org/dromara/service/api/RemoteStoreServiceService.java
  2. 6 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
  3. 47 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysRegionController.java
  4. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysStoreController.java
  5. 12 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java
  6. 12 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
  7. 5 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysAppSetting.java
  8. 53 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRegion.java
  9. 27 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantResetPwdBo.java
  10. 8 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysAppSettingVo.java
  11. 13 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRegionMapper.java
  12. 35 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysRegionService.java
  13. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysStoreService.java
  14. 6 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantService.java
  15. 1 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysAgreementServiceImpl.java
  16. 156 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRegionServiceImpl.java
  17. 11 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysStoreServiceImpl.java
  18. 16 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java
  19. 1 1
      ruoyi-modules/yingpaipay-archieves/src/main/java/org/dromara/archieves/constants/ChangeLogTypeConstants.java
  20. 2 2
      ruoyi-modules/yingpaipay-archieves/src/main/java/org/dromara/archieves/controller/UsrCustomerController.java
  21. 5 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfComplaintController.java
  22. 11 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfComplaintLog.java
  23. 11 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/bo/FlfComplaintLogBo.java
  24. 19 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/vo/FlfComplaintLogVo.java
  25. 2 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfComplaintLogService.java
  26. 11 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfComplaintLogServiceImpl.java
  27. 6 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfFulfillerServiceImpl.java
  28. 4 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/controller/SysSubOrderController.java
  29. 25 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderFeeStatisticBo.java
  30. 40 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/vo/SysSubOrderFeeStatisticPageVo.java
  31. 2 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/ISysSubOrderService.java
  32. 37 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysSubOrderServiceImpl.java
  33. 17 8
      ruoyi-modules/yingpaipay-service/src/main/java/org/dromara/service/dubbo/RemoteStoreServiceServiceImpl.java
  34. 16 1
      script/sql/business/v2/create.sql
  35. 21 0
      script/sql/business/v2/update.sql

+ 8 - 0
ruoyi-api/yingpaipay-api-service/src/main/java/org/dromara/service/api/RemoteStoreServiceService.java

@@ -7,4 +7,12 @@ public interface RemoteStoreServiceService {
     boolean insertBatch(Long storeId, List<Long> serviceIds, boolean cleanFlag);
 
     Map<Long, List<Long>> getByIds(List<Long> storeIds);
+
+    /**
+     * 根据服务类型获取可以提供该服务的门店ID列表
+     * @param serviceId 服务类型ID
+     * @return 门店ID列表
+     * @Author: Antigravity
+     */
+    List<Long> getStoreIdsByServiceId(Long serviceId);
 }

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

@@ -193,4 +193,10 @@ public interface CacheNames {
      * @Author: Huanyi
      */
     String SYS_SERVICE_CLASSIFICATION = GlobalConstants.GLOBAL_REDIS_KEY + "sys_service_classification#30d";
+
+    /**
+     * 地区信息
+     * @Author: Antigravity
+     */
+    String SYS_REGION = GlobalConstants.GLOBAL_REDIS_KEY + "sys_region#30d";
 }

+ 47 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysRegionController.java

@@ -0,0 +1,47 @@
+package org.dromara.system.controller.system;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.R;
+import org.dromara.system.domain.SysRegion;
+import org.springframework.web.bind.annotation.*;
+
+import org.dromara.system.service.ISysRegionService;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 地区数据处理控制器
+ *
+ * @Author: Antigravity
+ */
+@Slf4j
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/region")
+public class SysRegionController {
+
+    private final ISysRegionService regionService;
+
+    /**
+     * 接收并同步保存前端传来的地区数据
+     *
+     * @param regionData 地区数据列表
+     */
+    @PostMapping("/upload")
+    public R<Void> uploadRegionData(@RequestBody List<Map<String, Object>> regionData) {
+        log.info("开始同步前端发送的地区数据...");
+        regionService.syncRegionData(regionData);
+        return R.ok("数据源同步并持久化成功");
+    }
+
+    /**
+     * 获取地区树列表
+     */
+    @GetMapping("/listTree")
+    public R<List<SysRegion>> listTree() {
+        List<SysRegion> tree = regionService.selectRegionTree();
+        return R.ok(tree);
+    }
+}

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysStoreController.java

@@ -129,8 +129,9 @@ public class SysStoreController extends BaseController {
     public TableDataInfo<SysStoreListOnOrderVo> listOnOrder(
         @RequestParam(name = "name", required = false) String name,
         @RequestParam(name = "site", required = false) Long site,
+        @RequestParam(name = "serviceId", required = false) Long serviceId,
         PageQuery pageQuery) {
-        return sysStoreService.listOnOrder(name, site,  pageQuery);
+        return sysStoreService.listOnOrder(name, site, serviceId, pageQuery);
     }
 
     @RepeatSubmit()

+ 12 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java

@@ -19,6 +19,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.tenant.helper.TenantHelper;
 import org.dromara.system.domain.bo.SysTenantBo;
 import org.dromara.system.domain.bo.SysTenantEditOnMerchantBo;
+import org.dromara.system.domain.bo.SysTenantResetPwdBo;
 import org.dromara.system.domain.vo.SysTenantOnStoreVo;
 import org.dromara.system.domain.vo.SysTenantVo;
 import org.dromara.system.service.ISysTenantService;
@@ -226,4 +227,15 @@ public class SysTenantController extends BaseController {
         return toAjax(tenantService.updateOnMerchant(bo));
     }
 
+    /**
+     * 重置管理员密码
+     */
+    @ApiEncrypt
+    @Log(title = "租户管理", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping("/resetAdminPwd")
+    public R<Void> resetAdminPwd(@Validated @RequestBody SysTenantResetPwdBo bo) {
+        return toAjax(tenantService.resetAdminPwd(bo));
+    }
+
 }

+ 12 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java

@@ -220,6 +220,18 @@ public class SysUserController extends BaseController {
         return toAjax(userService.deleteUserByIds(userIds));
     }
 
+    /**
+     * 账号注销
+     * @Author: Antigravity
+     */
+    @Log(title = "用户管理", businessType = BusinessType.DELETE)
+    @DeleteMapping("/cancel")
+    public R<Void> cancel() {
+        Long userId = LoginHelper.getUserId();
+        userService.checkUserAllowed(userId);
+        return toAjax(userService.deleteUserByIds(new Long[]{userId}));
+    }
+
     /**
      * 根据用户ID串批量获取用户基础信息
      *

+ 5 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysAppSetting.java

@@ -15,4 +15,9 @@ public class SysAppSetting {
 
     private Long loginBackground;
 
+    /**
+     * 首页轮播图OSS ID,多个用逗号分隔 @Author: Antigravity
+     */
+    private String homeBanner;
+
 }

+ 53 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysRegion.java

@@ -0,0 +1,53 @@
+package org.dromara.system.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+/**
+ * 地区信息对象 sys_region
+ *
+ * @Author: Antigravity
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("sys_region")
+public class SysRegion extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 父级id
+     */
+    private Long parentId;
+
+    /**
+     * 地区代码
+     */
+    private String code;
+
+    /**
+     * 地区名称
+     */
+    private String name;
+
+    /**
+     * 租户编号
+     */
+    private String tenantId;
+
+    /**
+     * 子级列表
+     */
+    @com.baomidou.mybatisplus.annotation.TableField(exist = false)
+    private java.util.List<SysRegion> children = new java.util.ArrayList<>();
+
+}

+ 27 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantResetPwdBo.java

@@ -0,0 +1,27 @@
+package org.dromara.system.domain.bo;
+
+import lombok.Data;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
+/**
+ * 租户管理员重置密码业务对象
+ *
+ * @author Antigravity
+ */
+@Data
+public class SysTenantResetPwdBo {
+
+    /**
+     * 品牌id
+     */
+    @NotNull(message = "id不能为空")
+    private Long id;
+
+    /**
+     * 新密码
+     */
+    @NotBlank(message = "新密码不能为空")
+    private String newPassword;
+
+}

+ 8 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysAppSettingVo.java

@@ -28,4 +28,12 @@ public class SysAppSettingVo implements Serializable {
     @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "loginBackground")
     private String loginBackgroundUrl;
 
+    /**
+     * 首页轮播图OSS ID,多个用逗号分隔 @Author: Antigravity
+     */
+    private String homeBanner;
+
+    @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "homeBanner")
+    private String homeBannerUrls;
+
 }

+ 13 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysRegionMapper.java

@@ -0,0 +1,13 @@
+package org.dromara.system.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.system.domain.SysRegion;
+
+/**
+ * 地区信息Mapper接口
+ *
+ * @Author: Antigravity
+ */
+public interface SysRegionMapper extends BaseMapperPlus<SysRegion, SysRegion> {
+
+}

+ 35 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysRegionService.java

@@ -0,0 +1,35 @@
+package org.dromara.system.service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 地区信息Service接口
+ *
+ * @Author: Antigravity
+ */
+public interface ISysRegionService {
+
+    /**
+     * 批量同步并保存地区数据
+     *
+     * @param regionData 地区原始数据列表
+     */
+    void syncRegionData(List<Map<String, Object>> regionData);
+
+    /**
+     * 根据代码查询地区信息
+     *
+     * @param code 地区代码
+     * @return 地区信息
+     */
+    org.dromara.system.domain.SysRegion selectByCode(String code);
+
+    /**
+     * 查询地区树结构
+     *
+     * @return 地区树列表
+     */
+    java.util.List<org.dromara.system.domain.SysRegion> selectRegionTree();
+
+}

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysStoreService.java

@@ -75,7 +75,7 @@ public interface ISysStoreService {
 
     List<Long> selectStoreIds(Long userId);
 
-    TableDataInfo<SysStoreListOnOrderVo> listOnOrder(String name, Long site, PageQuery pageQuery);
+    TableDataInfo<SysStoreListOnOrderVo> listOnOrder(String name, Long site, Long serviceId, PageQuery pageQuery);
 
     boolean renew(SysStoreRenewBo bo);
 

+ 6 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantService.java

@@ -4,6 +4,7 @@ import org.dromara.system.domain.bo.SysTenantEditOnMerchantBo;
 import org.dromara.system.domain.vo.SysTenantOnStoreVo;
 import org.dromara.system.domain.vo.SysTenantVo;
 import org.dromara.system.domain.bo.SysTenantBo;
+import org.dromara.system.domain.bo.SysTenantResetPwdBo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 
@@ -95,4 +96,9 @@ public interface ISysTenantService {
     TableDataInfo<SysTenantOnStoreVo> listOnStore(PageQuery pageQuery);
 
     boolean updateOnMerchant(SysTenantEditOnMerchantBo bo);
+
+    /**
+     * 重置管理员密码
+     */
+    Boolean resetAdminPwd(SysTenantResetPwdBo bo);
 }

+ 1 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysAgreementServiceImpl.java

@@ -34,6 +34,7 @@ public class SysAgreementServiceImpl implements ISysAgreementService {
     @Override
     public SysAgreement updateById(SysAgreement agreement) {
         agreement.setContent(new String(Base64.getDecoder().decode(agreement.getContent()), StandardCharsets.UTF_8));
+        baseMapper.updateById(agreement);
         return baseMapper.selectById(agreement.getId());
     }
 

+ 156 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRegionServiceImpl.java

@@ -0,0 +1,156 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.tree.Tree;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.constant.CacheNames;
+import org.dromara.common.core.utils.TreeBuildUtils;
+import org.dromara.common.redis.utils.CacheUtils;
+import org.dromara.system.domain.SysRegion;
+import org.dromara.system.mapper.SysRegionMapper;
+import org.dromara.system.service.ISysRegionService;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 地区信息Service业务层处理
+ *
+ * @Author: Antigravity
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class SysRegionServiceImpl implements ISysRegionService {
+
+    private final SysRegionMapper baseMapper;
+
+    /**
+     * 批量同步并保存地区数据
+     *
+     * @param regionData 地区原始数据列表
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void syncRegionData(List<Map<String, Object>> regionData) {
+        // 1. 同步前先清除历史数据(防止重复同步产生垃圾数据)
+        baseMapper.delete(new LambdaQueryWrapper<SysRegion>());
+        // 2. 清除所有相关缓存
+        CacheUtils.clear(CacheNames.SYS_REGION);
+        // 3. 递归保存
+        saveRecursive(regionData, 0L);
+        log.info("地区数据同步完成");
+    }
+
+    /**
+     * 递归保存子节点
+     */
+    private void saveRecursive(List<Map<String, Object>> data, Long parentId) {
+        if (data == null || data.isEmpty()) {
+            return;
+        }
+        for (Map<String, Object> map : data) {
+            String code = String.valueOf(map.get("value"));
+            String name = String.valueOf(map.get("label"));
+
+            SysRegion region = new SysRegion();
+            region.setId(IdWorker.getId());
+            region.setParentId(parentId);
+            region.setCode(code);
+            region.setName(name);
+            // 每一个插入项都可能被 CachePut,但在批量保存时通常直接清理总缓存更有效
+            // 此处满足用户对 CachePut 的参考需求,实际通过 syncRegionData 整体维护
+            this.insertRegionWithCache(region);
+
+            Object children = map.get("children");
+            if (children instanceof List) {
+                saveRecursive((List<Map<String, Object>>) children, region.getId());
+            }
+        }
+    }
+
+    /**
+     * 带缓存的新增(参考 CachePut 用法)
+     */
+    @CachePut(cacheNames = CacheNames.SYS_REGION, key = "#region.code")
+    public SysRegion insertRegionWithCache(SysRegion region) {
+        baseMapper.insert(region);
+        return region;
+    }
+
+    /**
+     * 根据代码查询地区信息(参考 Cacheable 用法)
+     */
+    @Cacheable(cacheNames = CacheNames.SYS_REGION, key = "#code")
+    @Override
+    public SysRegion selectByCode(String code) {
+        return baseMapper.selectOne(new LambdaQueryWrapper<SysRegion>()
+            .eq(SysRegion::getCode, code));
+    }
+
+    /**
+     * 查询地区树结构
+     */
+    @Cacheable(cacheNames = CacheNames.SYS_REGION, key = "'tree'")
+    @Override
+    public List<SysRegion> selectRegionTree() {
+        List<SysRegion> list = baseMapper.selectList(new LambdaQueryWrapper<SysRegion>()
+            .orderByAsc(SysRegion::getCode));
+        return buildRegionTree(list, 0L);
+    }
+
+    /**
+     * 构建地区树
+     */
+    private List<SysRegion> buildRegionTree(List<SysRegion> list, Long parentId) {
+        List<SysRegion> returnList = new java.util.ArrayList<>();
+        for (SysRegion region : list) {
+            if (region.getParentId().equals(parentId)) {
+                recursionFn(list, region);
+                returnList.add(region);
+            }
+        }
+        return returnList;
+    }
+
+    /**
+     * 递归列表
+     */
+    private void recursionFn(List<SysRegion> list, SysRegion t) {
+        List<SysRegion> childList = getChildList(list, t);
+        t.setChildren(childList);
+        for (SysRegion tChild : childList) {
+            if (hasChild(list, tChild)) {
+                recursionFn(list, tChild);
+            }
+        }
+    }
+
+    /**
+     * 得到子节点列表
+     */
+    private List<SysRegion> getChildList(List<SysRegion> list, SysRegion t) {
+        List<SysRegion> tlist = new java.util.ArrayList<>();
+        for (SysRegion n : list) {
+            if (n.getParentId().equals(t.getId())) {
+                tlist.add(n);
+            }
+        }
+        return tlist;
+    }
+
+    /**
+     * 判断是否有子节点
+     */
+    private boolean hasChild(List<SysRegion> list, SysRegion t) {
+        return !getChildList(list, t).isEmpty();
+    }
+
+}

+ 11 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysStoreServiceImpl.java

@@ -299,7 +299,7 @@ public class SysStoreServiceImpl implements ISysStoreService {
     }
 
     @Override
-    public TableDataInfo<SysStoreListOnOrderVo> listOnOrder(String name, Long site, PageQuery pageQuery) {
+    public TableDataInfo<SysStoreListOnOrderVo> listOnOrder(String name, Long site, Long serviceId, PageQuery pageQuery) {
 
         LambdaQueryWrapper<SysStore> wrapper = Wrappers.lambdaQuery(SysStore.class)
             .like(StringUtils.isNotBlank(name), SysStore::getName, name)
@@ -314,6 +314,16 @@ public class SysStoreServiceImpl implements ISysStoreService {
             wrapper.in(SysStore::getId, WrapperUtils.convertIds(storeIds));
         }
 
+        // @Author: Antigravity
+        // 如果提供了服务ID,则过滤出能提供该服务的门店
+        if (serviceId != null) {
+            List<Long> storesWithService = remoteStoreServiceService.getStoreIdsByServiceId(serviceId);
+            if (storesWithService.isEmpty()) {
+                return TableDataInfo.build(new Page<>());
+            }
+            wrapper.in(SysStore::getId, storesWithService);
+        }
+
         Page<SysStore> page = baseMapper.selectPage(pageQuery.build(), wrapper);
 
         List<Long> ids = new ArrayList<>();

+ 16 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantServiceImpl.java

@@ -31,6 +31,7 @@ import org.dromara.system.constants.StoreConstants;
 import org.dromara.system.domain.*;
 import org.dromara.system.domain.bo.SysTenantBo;
 import org.dromara.system.domain.bo.SysTenantEditOnMerchantBo;
+import org.dromara.system.domain.bo.SysTenantResetPwdBo;
 import org.dromara.system.domain.vo.SysTenantOnStoreVo;
 import org.dromara.system.domain.vo.SysTenantVo;
 import org.dromara.system.mapper.*;
@@ -633,4 +634,19 @@ public class SysTenantServiceImpl implements ISysTenantService {
         return baseMapper.updateById(tenant) > 0;
     }
 
+    @Override
+    public Boolean resetAdminPwd(SysTenantResetPwdBo bo) {
+        SysTenant tenant = baseMapper.selectById(bo.getId());
+        if (ObjectUtil.isNull(tenant)) {
+            throw new ServiceException("品牌不存在");
+        }
+        if (ObjectUtil.isNull(tenant.getAdmin())) {
+            throw new ServiceException("该品牌无管理员");
+        }
+        SysUser user = new SysUser();
+        user.setUserId(tenant.getAdmin());
+        user.setPassword(BCrypt.hashpw(bo.getNewPassword()));
+        return userMapper.updateById(user) > 0;
+    }
+
 }

+ 1 - 1
ruoyi-modules/yingpaipay-archieves/src/main/java/org/dromara/archieves/constants/ChangeLogTypeConstants.java

@@ -14,7 +14,7 @@ public interface ChangeLogTypeConstants {
     String CUSTOMER_ADD_PET = "customer_add_pet";
     String CUSTOMER_CREATE = "customer_create";
     String CUSTOMER_EDIT = "customer_edit";
-    String CUSTOMER_CHANGE_STATUS = "customer_change_satus";
+    String CUSTOMER_CHANGE_STATUS = "customer_change_status";
     String CUSTOMER_REMOVE = "customer_remove";
     String CUSTOMER_REMARK = "customer_remark";
 

+ 2 - 2
ruoyi-modules/yingpaipay-archieves/src/main/java/org/dromara/archieves/controller/UsrCustomerController.java

@@ -129,8 +129,8 @@ public class UsrCustomerController extends BaseController {
     @Log(title = "用户管理", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PutMapping("/changeStatus")
-    public R<Void> changeStatus(@RequestParam Long id, @RequestParam Integer status) {
-        return toAjax(usrCustomerService.changeStatus(id, status));
+    public R<Void> changeStatus(@RequestBody UsrCustomerBo bo) {
+        return toAjax(usrCustomerService.changeStatus(bo.getId(), bo.getStatus()));
     }
 
     @GetMapping("/listOnOrder")

+ 5 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfComplaintController.java

@@ -39,4 +39,9 @@ public class FlfComplaintController extends BaseController {
         return flfComplaintLogService.pageByFulfiller(fulfiller, pageQuery);
     }
 
+    @GetMapping("/pageMy")
+    public TableDataInfo<FlfComplaintLogVo> pageMy(PageQuery pageQuery) {
+        return flfComplaintLogService.pageMyComplaint(pageQuery);
+    }
+
 }

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

@@ -42,6 +42,16 @@ public class FlfComplaintLog extends TenantEntity {
      */
     private String reason;
 
+    /**
+     * 评价图片
+     */
+    private String photos;
+
+    /**
+     * 是否好评(true:好评, false:差评/投诉)
+     */
+    private Boolean praiseFlag;
+
     /**
      * 删除标志(0代表存在 1代表删除)
      */
@@ -49,4 +59,5 @@ public class FlfComplaintLog extends TenantEntity {
     private String delFlag;
 
 
+
 }

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

@@ -43,4 +43,15 @@ public class FlfComplaintLogBo extends BaseEntity {
      */
     private String reason;
 
+    /**
+     * 评价图片
+     */
+    private String photos;
+
+    /**
+     * 是否好评(true:好评, false:差评/投诉)
+     */
+    private Boolean praiseFlag;
+
+
 }

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

@@ -57,8 +57,27 @@ public class FlfComplaintLogVo implements Serializable {
     @ExcelProperty(value = "投诉原因")
     private String reason;
 
+    /**
+     * 评价图片
+     */
+    @ExcelProperty(value = "评价图片")
+    private String photos;
+
+    /**
+     * 评价图片预览
+     */
+    @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "photos")
+    private String photoUrls;
+
+    /**
+     * 是否好评(true:好评, false:差评/投诉)
+     */
+    @ExcelProperty(value = "是否好评")
+    private Boolean praiseFlag;
+
     private Date createTime;
 
+
     @Translation(type = TransConstant.USER_ID_TO_NAME, mapper = "createBy")
     private Long createBy;
 

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

@@ -19,4 +19,6 @@ public interface IFlfComplaintLogService {
     List<FlfComplaintLogVo> listByOrder(Long orderId);
 
     TableDataInfo<FlfComplaintLogVo> pageByFulfiller(Long fulfiller, PageQuery pageQuery);
+
+    TableDataInfo<FlfComplaintLogVo> pageMyComplaint(PageQuery pageQuery);
 }

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

@@ -61,4 +61,15 @@ public class FlfComplaintLogServiceImpl implements IFlfComplaintLogService {
         );
         return TableDataInfo.build(page);
     }
+
+    @Override
+    public TableDataInfo<FlfComplaintLogVo> pageMyComplaint(PageQuery pageQuery) {
+        IPage<FlfComplaintLogVo> page = baseMapper.selectVoPage(
+            pageQuery.build(),
+            Wrappers.lambdaQuery(FlfComplaintLog.class)
+                .eq(FlfComplaintLog::getCreateBy, org.dromara.common.satoken.utils.LoginHelper.getUserId())
+                .orderByDesc(FlfComplaintLog::getId)
+        );
+        return TableDataInfo.build(page);
+    }
 }

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

@@ -181,6 +181,12 @@ public class FlfFulfillerServiceImpl implements IFlfFulfillerService {
     @Transactional(rollbackFor = Exception.class)
     public Boolean updateByBo(FlfFulfillerBo bo) {
         FlfFulfiller update = MapstructUtils.convert(bo, FlfFulfiller.class);
+        // 密码处理:有值则BCrypt加密,无值则置null避免覆盖原密码 @Author: Antigravity
+        if (StringUtils.isNotBlank(bo.getPassword())) {
+            update.setPassword(BCrypt.hashpw(bo.getPassword()));
+        } else {
+            update.setPassword(null);
+        }
         validEntityBeforeSave(update);
         boolean flag = baseMapper.updateById(update) > 0;
         if (flag) {

+ 4 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/controller/SysSubOrderController.java

@@ -217,4 +217,8 @@ public class SysSubOrderController extends BaseController {
         return toAjax(subOrderService.activate(bo));
     }
 
+    @GetMapping("/listOnFeeStatistic")
+    public TableDataInfo<SysSubOrderFeeStatisticPageVo> listOnFeeStatistic(SysSubOrderFeeStatisticBo bo, PageQuery pageQuery) {
+        return subOrderService.listOnFeeStatistic(bo, pageQuery);
+    }
 }

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

@@ -0,0 +1,25 @@
+package org.dromara.order.domain.bo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.io.Serializable;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class SysSubOrderFeeStatisticBo extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 门店ID
+     */
+    private Long storeId;
+
+    /**
+     * 月份或者时间(前端可以选择天或者范围,也可以放到params里)
+     */
+    private String dateRange;
+
+}

+ 40 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/vo/SysSubOrderFeeStatisticPageVo.java

@@ -0,0 +1,40 @@
+package org.dromara.order.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class SysSubOrderFeeStatisticPageVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 订单号
+     */
+    private String code;
+
+    /**
+     * 订单佣金(分)
+     */
+    private Long orderCommission;
+
+    /**
+     * 团购套餐名称
+     */
+    private String groupPurchasePackageName;
+
+    /**
+     * 服务ID
+     */
+    private Long service;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+}

+ 2 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/ISysSubOrderService.java

@@ -49,4 +49,6 @@ public interface ISysSubOrderService {
     List<SysSubOrderListPageVo> listExcel(SysSubOrderListPageBo bo);
 
     boolean activate(SysSubOrderActivateBo bo);
+
+    TableDataInfo<SysSubOrderFeeStatisticPageVo> listOnFeeStatistic(SysSubOrderFeeStatisticBo bo, PageQuery pageQuery);
 }

+ 37 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysSubOrderServiceImpl.java

@@ -1113,4 +1113,41 @@ public class SysSubOrderServiceImpl implements ISysSubOrderService {
             .set(SysSubOrder::getFulfillmentCommission, bo.getFulfillmentCommission())
             .set(SysSubOrder::getServiceFlag, true)) > 0;
     }
+
+    @Override
+    public TableDataInfo<SysSubOrderFeeStatisticPageVo> listOnFeeStatistic(SysSubOrderFeeStatisticBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<SysSubOrder> wrapper = Wrappers.lambdaQuery(SysSubOrder.class)
+            // .eq(bo.getStoreId() != null, SysSubOrder::getStore, bo.getStoreId()) // 根据需要过滤商店
+            .eq(SysSubOrder::getStatus, OrderStatusEnum.COMPLETED.getValue()) // 假设只统计已完成的订单(赚到的费用)
+            .orderByDesc(SysSubOrder::getId);
+
+        if (bo.getParams() != null && bo.getParams().get("beginTime") != null && bo.getParams().get("endTime") != null) {
+            wrapper.between(SysSubOrder::getCreateTime, bo.getParams().get("beginTime"), bo.getParams().get("endTime"));
+        }
+
+        // 可以加上当前用户的权限过滤等如果需要,例如:
+        // wrapper.in(SysSubOrder::getStoreSite, WrapperUtils.convertIds(remoteAreaStationService.listByUserId(LoginHelper.getUserId())));
+        
+        Page<SysSubOrder> page = baseMapper.selectPage(pageQuery.build(), wrapper);
+
+        // 如果需要返回服务名称,收集serviceId
+        List<Long> serviceIds = new ArrayList<>();
+        page.getRecords().forEach(e -> {
+            if (e.getService() != null) {
+                serviceIds.add(e.getService());
+            }
+        });
+        
+        // 实际上可以用 RemoteSysServiceService 获取,由于在这个类里没有直接依赖,如果需要可以使用 getByIds (这里暂略或根据实际注入)
+        // 简单处理:
+        return TableDataInfo.build(page.convert(e -> {
+            SysSubOrderFeeStatisticPageVo vo = new SysSubOrderFeeStatisticPageVo();
+            vo.setService(e.getService()); // 返回服务ID给前端
+            vo.setCode(e.getCode());
+            vo.setOrderCommission(e.getOrderCommission()); // 订单佣金
+            vo.setGroupPurchasePackageName(e.getGroupPurchasePackageName()); // 团购套餐
+            vo.setCreateTime(e.getCreateTime());
+            return vo;
+        }));
+    }
 }

+ 17 - 8
ruoyi-modules/yingpaipay-service/src/main/java/org/dromara/service/dubbo/RemoteStoreServiceServiceImpl.java

@@ -21,15 +21,8 @@ public class RemoteStoreServiceServiceImpl implements RemoteStoreServiceService
     @Override
     public boolean insertBatch(Long storeId, List<Long> serviceIds, boolean cleanFlag) {
 
-
         if (cleanFlag) {
-            boolean deleteFlag = baseMapper.delete(
-                Wrappers.lambdaQuery(SysStoreService.class)
-                    .eq(SysStoreService::getStoreId, storeId)
-            ) == 0;
-            if (deleteFlag) {
-                throw new RuntimeException("批量删除失败");
-            }
+            baseMapper.delete(Wrappers.lambdaQuery(SysStoreService.class).eq(SysStoreService::getStoreId, storeId));
         }
 
         if (!serviceIds.isEmpty()) {
@@ -62,4 +55,20 @@ public class RemoteStoreServiceServiceImpl implements RemoteStoreServiceService
 
         return map;
     }
+
+    /**
+     * 根据服务类型获取可以提供该服务的门店ID列表
+     * @param serviceId 服务类型ID
+     * @return 门店ID列表
+     * @Author: Antigravity
+     */
+    @Override
+    public List<Long> getStoreIdsByServiceId(Long serviceId) {
+        if (serviceId == null) {
+            return Collections.emptyList();
+        }
+        List<SysStoreService> list = baseMapper.selectList(Wrappers.lambdaQuery(SysStoreService.class)
+            .eq(SysStoreService::getServiceId, serviceId));
+        return list.stream().map(SysStoreService::getStoreId).distinct().toList();
+    }
 }

+ 16 - 1
script/sql/business/v2/create.sql

@@ -29,6 +29,21 @@ CREATE TABLE pet_system.sys_sub_order_appeal
     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 `sys_region` (
+    `id`          bigint(20)   NOT NULL COMMENT '主键',
+    `parent_id`   bigint(20)   DEFAULT 0 COMMENT '父级id',
+    `code`        varchar(64)  NOT NULL COMMENT '地区代码',
+    `name`        varchar(128) NOT NULL COMMENT '地区名称',
+    `del_flag`    char(1)      DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
+    `create_dept` bigint(20)   DEFAULT NULL COMMENT '创建部门',
+    `create_by`   bigint(20)   DEFAULT NULL COMMENT '创建者',
+    `create_time` datetime     DEFAULT NULL COMMENT '创建时间',
+    `update_by`   bigint(20)   DEFAULT NULL COMMENT '更新者',
+    `update_time` datetime     DEFAULT NULL COMMENT '更新时间',
+    `tenant_id`   varchar(20)  DEFAULT NULL COMMENT '租户编号',
+    PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='地区信息表';

+ 21 - 0
script/sql/business/v2/update.sql

@@ -28,3 +28,24 @@ ALTER TABLE pet_system.sys_sub_order ADD COLUMN order_commission bigint COMMENT
 ALTER TABLE pet_system.sys_sub_order CHANGE price fulfillment_commission bigint COMMENT '履约佣金';
 
 ALTER TABLE pet_system.sys_sub_order ADD COLUMN service_flag boolean DEFAULT true COMMENT '是否可以服务';
+
+INSERT INTO pet_system.sys_agreement(id, title, content)
+VALUES (5, '宠物洗护服务规范', '');
+
+-- 首页轮播图配置(存储OSS文件ID,多个用逗号分隔) @Author: Antigravity
+ALTER TABLE pet_system.sys_app_setting ADD COLUMN home_banner varchar(500) DEFAULT NULL COMMENT '首页轮播图OSS ID,多个用逗号分隔';
+
+-- 插入好萌友(ID=2)的应用配置基础数据 @Author: Antigravity
+INSERT INTO pet_system.sys_app_setting (id)
+VALUES (2);
+
+-- 插入好萌友(ID=2)的客服配置基础数据 @Author: Antigravity
+INSERT INTO pet_system.sys_customer_service_setting (id, wechat_account, phone_number, start_service_time, end_service_time, qr_code, enterprise_wechat_link)
+VALUES (2, NULL, NULL, '09:00:00', '18:00:00', NULL, NULL);
+
+-- 投诉/评价表增加字段 @Author: Antigravity
+ALTER TABLE pet_system.flf_complaint_log ADD COLUMN photos varchar(500) COMMENT '评价图片ID,多个用逗号分隔';
+ALTER TABLE pet_system.flf_complaint_log ADD COLUMN praise_flag boolean DEFAULT false COMMENT '是否好评(true:好评, false:差评/投诉)';
+
+
+