Răsfoiți Sursa

feat(product): 新增频道页面配置和楼层管理功能

- 添加 ClientSiteChannelPage 实体类及相关业务对象
- 实现频道页面配置的增删改查控制器和业务逻辑
- 添加 ClientSiteFloor 和 ClientSiteFloorLink 实体类及业务对象
- 实现楼层管理和楼层关联功能的完整业务逻辑
- 修复 ClientSite 中协议文件路径字段命名不一致问题
- 更新相关日期注释和代码结构优化
肖路 1 lună în urmă
părinte
comite
eebde3e10a
56 a modificat fișierele cu 2378 adăugiri și 72 ștergeri
  1. 106 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteChannelPageController.java
  2. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteController.java
  3. 106 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteFloorController.java
  4. 106 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteFloorLinkController.java
  5. 141 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteProductController.java
  6. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteSettingController.java
  7. 101 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/SiteProductController.java
  8. 2 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSite.java
  9. 76 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSiteChannelPage.java
  10. 87 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSiteFloor.java
  11. 82 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSiteFloorLink.java
  12. 8 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSiteProduct.java
  13. 5 10
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSiteSetting.java
  14. 2 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteBo.java
  15. 82 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteChannelPageBo.java
  16. 89 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteFloorBo.java
  17. 82 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteFloorLinkBo.java
  18. 9 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteProductBo.java
  19. 4 9
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteSettingBo.java
  20. 5 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProductBaseBo.java
  21. 93 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteChannelPageVo.java
  22. 94 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteFloorLinkVo.java
  23. 100 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteFloorVo.java
  24. 33 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteProductImportVo.java
  25. 8 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteProductVo.java
  26. 5 10
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteSettingVo.java
  27. 2 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteVo.java
  28. 9 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductBaseVo.java
  29. 133 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/listener/ClientSiteProductImportListener.java
  30. 15 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteChannelPageMapper.java
  31. 15 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteFloorLinkMapper.java
  32. 15 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteFloorMapper.java
  33. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteMapper.java
  34. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteProductMapper.java
  35. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteSettingMapper.java
  36. 70 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteChannelPageService.java
  37. 70 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteFloorLinkService.java
  38. 70 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteFloorService.java
  39. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteProductService.java
  40. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteService.java
  41. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteSettingService.java
  42. 10 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductBaseService.java
  43. 9 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductBrandService.java
  44. 142 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteChannelPageServiceImpl.java
  45. 141 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteFloorLinkServiceImpl.java
  46. 142 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteFloorServiceImpl.java
  47. 1 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteProductServiceImpl.java
  48. 2 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteServiceImpl.java
  49. 3 3
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteSettingServiceImpl.java
  50. 47 14
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseServiceImpl.java
  51. 24 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBrandServiceImpl.java
  52. 2 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductCategoryServiceImpl.java
  53. 7 0
      ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ClientSiteChannelPageMapper.xml
  54. 7 0
      ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ClientSiteFloorLinkMapper.xml
  55. 7 0
      ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ClientSiteFloorMapper.xml
  56. 1 0
      ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductBaseMapper.xml

+ 106 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteChannelPageController.java

@@ -0,0 +1,106 @@
+package org.dromara.product.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+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.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.product.domain.vo.ClientSiteChannelPageVo;
+import org.dromara.product.domain.bo.ClientSiteChannelPageBo;
+import org.dromara.product.service.IClientSiteChannelPageService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 频道页面配置
+ * 前端访问路由地址为:/product/siteChannelPage
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/siteChannelPage")
+public class ClientSiteChannelPageController extends BaseController {
+
+    private final IClientSiteChannelPageService clientSiteChannelPageService;
+
+    /**
+     * 查询频道页面配置列表
+     */
+    //@SaCheckPermission("product:siteChannelPage:list")
+    @GetMapping("/list")
+    public TableDataInfo<ClientSiteChannelPageVo> list(ClientSiteChannelPageBo bo, PageQuery pageQuery) {
+        return clientSiteChannelPageService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出频道页面配置列表
+     */
+    //@SaCheckPermission("product:siteChannelPage:export")
+    @Log(title = "频道页面配置", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(ClientSiteChannelPageBo bo, HttpServletResponse response) {
+        List<ClientSiteChannelPageVo> list = clientSiteChannelPageService.queryList(bo);
+        ExcelUtil.exportExcel(list, "频道页面配置", ClientSiteChannelPageVo.class, response);
+    }
+
+    /**
+     * 获取频道页面配置详细信息
+     *
+     * @param id 主键
+     */
+    //@SaCheckPermission("product:siteChannelPage:query")
+    @GetMapping("/{id}")
+    public R<ClientSiteChannelPageVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(clientSiteChannelPageService.queryById(id));
+    }
+
+    /**
+     * 新增频道页面配置
+     */
+    //@SaCheckPermission("product:siteChannelPage:add")
+    @Log(title = "频道页面配置", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody ClientSiteChannelPageBo bo) {
+        return toAjax(clientSiteChannelPageService.insertByBo(bo));
+    }
+
+    /**
+     * 修改频道页面配置
+     */
+    //@SaCheckPermission("product:siteChannelPage:edit")
+    @Log(title = "频道页面配置", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ClientSiteChannelPageBo bo) {
+        return toAjax(clientSiteChannelPageService.updateByBo(bo));
+    }
+
+    /**
+     * 删除频道页面配置
+     *
+     * @param ids 主键串
+     */
+    //@SaCheckPermission("product:siteChannelPage:remove")
+    @Log(title = "频道页面配置", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(clientSiteChannelPageService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteController.java

@@ -27,7 +27,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
  * 前端访问路由地址为:/product/site
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Validated
 @RequiredArgsConstructor

+ 106 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteFloorController.java

@@ -0,0 +1,106 @@
+package org.dromara.product.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+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.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.product.domain.vo.ClientSiteFloorVo;
+import org.dromara.product.domain.bo.ClientSiteFloorBo;
+import org.dromara.product.service.IClientSiteFloorService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 客户站点楼层主
+ * 前端访问路由地址为:/product/siteFloor
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/siteFloor")
+public class ClientSiteFloorController extends BaseController {
+
+    private final IClientSiteFloorService clientSiteFloorService;
+
+    /**
+     * 查询客户站点楼层主列表
+     */
+    //@SaCheckPermission("product:siteFloor:list")
+    @GetMapping("/list")
+    public TableDataInfo<ClientSiteFloorVo> list(ClientSiteFloorBo bo, PageQuery pageQuery) {
+        return clientSiteFloorService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出客户站点楼层主列表
+     */
+    //@SaCheckPermission("product:siteFloor:export")
+    @Log(title = "客户站点楼层主", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(ClientSiteFloorBo bo, HttpServletResponse response) {
+        List<ClientSiteFloorVo> list = clientSiteFloorService.queryList(bo);
+        ExcelUtil.exportExcel(list, "客户站点楼层主", ClientSiteFloorVo.class, response);
+    }
+
+    /**
+     * 获取客户站点楼层主详细信息
+     *
+     * @param id 主键
+     */
+    //@SaCheckPermission("product:siteFloor:query")
+    @GetMapping("/{id}")
+    public R<ClientSiteFloorVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(clientSiteFloorService.queryById(id));
+    }
+
+    /**
+     * 新增客户站点楼层主
+     */
+    //@SaCheckPermission("product:siteFloor:add")
+    @Log(title = "客户站点楼层主", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody ClientSiteFloorBo bo) {
+        return toAjax(clientSiteFloorService.insertByBo(bo));
+    }
+
+    /**
+     * 修改客户站点楼层主
+     */
+    //@SaCheckPermission("product:siteFloor:edit")
+    @Log(title = "客户站点楼层主", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ClientSiteFloorBo bo) {
+        return toAjax(clientSiteFloorService.updateByBo(bo));
+    }
+
+    /**
+     * 删除客户站点楼层主
+     *
+     * @param ids 主键串
+     */
+    //@SaCheckPermission("product:siteFloor:remove")
+    @Log(title = "客户站点楼层主", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(clientSiteFloorService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 106 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteFloorLinkController.java

@@ -0,0 +1,106 @@
+package org.dromara.product.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+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.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.product.domain.vo.ClientSiteFloorLinkVo;
+import org.dromara.product.domain.bo.ClientSiteFloorLinkBo;
+import org.dromara.product.service.IClientSiteFloorLinkService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 客户站点楼层关联
+ * 前端访问路由地址为:/product/siteFloorLink
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/siteFloorLink")
+public class ClientSiteFloorLinkController extends BaseController {
+
+    private final IClientSiteFloorLinkService clientSiteFloorLinkService;
+
+    /**
+     * 查询客户站点楼层关联列表
+     */
+    //@SaCheckPermission("product:siteFloorLink:list")
+    @GetMapping("/list")
+    public TableDataInfo<ClientSiteFloorLinkVo> list(ClientSiteFloorLinkBo bo, PageQuery pageQuery) {
+        return clientSiteFloorLinkService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出客户站点楼层关联列表
+     */
+    //@SaCheckPermission("product:siteFloorLink:export")
+    @Log(title = "客户站点楼层关联", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(ClientSiteFloorLinkBo bo, HttpServletResponse response) {
+        List<ClientSiteFloorLinkVo> list = clientSiteFloorLinkService.queryList(bo);
+        ExcelUtil.exportExcel(list, "客户站点楼层关联", ClientSiteFloorLinkVo.class, response);
+    }
+
+    /**
+     * 获取客户站点楼层关联详细信息
+     *
+     * @param id 主键
+     */
+    //@SaCheckPermission("product:siteFloorLink:query")
+    @GetMapping("/{id}")
+    public R<ClientSiteFloorLinkVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(clientSiteFloorLinkService.queryById(id));
+    }
+
+    /**
+     * 新增客户站点楼层关联
+     */
+    //@SaCheckPermission("product:siteFloorLink:add")
+    @Log(title = "客户站点楼层关联", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody ClientSiteFloorLinkBo bo) {
+        return toAjax(clientSiteFloorLinkService.insertByBo(bo));
+    }
+
+    /**
+     * 修改客户站点楼层关联
+     */
+    //@SaCheckPermission("product:siteFloorLink:edit")
+    @Log(title = "客户站点楼层关联", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ClientSiteFloorLinkBo bo) {
+        return toAjax(clientSiteFloorLinkService.updateByBo(bo));
+    }
+
+    /**
+     * 删除客户站点楼层关联
+     *
+     * @param ids 主键串
+     */
+    //@SaCheckPermission("product:siteFloorLink:remove")
+    @Log(title = "客户站点楼层关联", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(clientSiteFloorLinkService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 141 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteProductController.java

@@ -1,13 +1,26 @@
 package org.dromara.product.controller;
 
 import java.util.List;
+import java.util.ArrayList;
 
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.easyes.core.biz.EsPageInfo;
+import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
+import org.dromara.product.domain.ClientSiteProduct;
+import org.dromara.product.domain.bo.ProductBaseBo;
+import org.dromara.product.domain.vo.PcProductVo;
+import org.dromara.product.domain.vo.ProductBaseVo;
+import org.dromara.product.esmapper.ProductEsMapper;
+import org.dromara.product.service.IProductBaseService;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
+import org.springframework.http.MediaType;
+import org.springframework.web.multipart.MultipartFile;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
 import org.dromara.common.log.annotation.Log;
 import org.dromara.common.web.core.BaseController;
@@ -17,9 +30,13 @@ import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.common.excel.core.ExcelResult;
 import org.dromara.product.domain.vo.ClientSiteProductVo;
 import org.dromara.product.domain.bo.ClientSiteProductBo;
 import org.dromara.product.service.IClientSiteProductService;
+import org.dromara.product.domain.vo.ClientSiteProductImportVo;
+import org.dromara.product.domain.vo.ClientSiteProductExportVo;
+import org.dromara.product.listener.ClientSiteProductImportListener;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 
 /**
@@ -27,7 +44,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
  * 前端访问路由地址为:/product/siteProduct
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Validated
 @RequiredArgsConstructor
@@ -37,6 +54,8 @@ public class ClientSiteProductController extends BaseController {
 
     private final IClientSiteProductService clientSiteProductService;
 
+    private final ProductEsMapper productEsMapper;
+
     /**
      * 查询客户站点产品配置列表
      */
@@ -65,7 +84,7 @@ public class ClientSiteProductController extends BaseController {
     //@SaCheckPermission("product:siteProduct:query")
     @GetMapping("/{id}")
     public R<ClientSiteProductVo> getInfo(@NotNull(message = "主键不能为空")
-                                     @PathVariable("id") Long id) {
+                                          @PathVariable("id") Long id) {
         return R.ok(clientSiteProductService.queryById(id));
     }
 
@@ -91,6 +110,21 @@ public class ClientSiteProductController extends BaseController {
         return toAjax(clientSiteProductService.updateByBo(bo));
     }
 
+    /**
+    * 更新协议价
+    * */
+    @Log(title = "客户站点产品配置", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping("/updateAgreementPrice")
+    public R<Void> updateAgreementPrice(@Validated @RequestBody ClientSiteProductBo bo) {
+        clientSiteProductService.update(Wrappers.lambdaUpdate(ClientSiteProduct.class)
+            .set(ClientSiteProduct::getAgreementPrice, bo.getAgreementPrice())
+            .eq(ClientSiteProduct::getSiteId, bo.getSiteId())
+            .eq(ClientSiteProduct::getProductId, bo.getProductId())
+        );
+        return R.ok();
+    }
+
     /**
      * 删除客户站点产品配置
      *
@@ -103,4 +137,109 @@ public class ClientSiteProductController extends BaseController {
                           @PathVariable("ids") Long[] ids) {
         return toAjax(clientSiteProductService.deleteWithValidByIds(List.of(ids), true));
     }
+
+    /**
+    * 获取站点下的产品数据
+    * */
+    @GetMapping("/getSiteProductPage")
+    public TableDataInfo<ProductBaseVo> getSiteProductPage(ProductBaseBo bo, PageQuery pageQuery) {
+        List<ClientSiteProduct> clientSiteProducts = clientSiteProductService.list(Wrappers.lambdaQuery(ClientSiteProduct.class)
+            .eq(ClientSiteProduct::getSiteId, bo.getSiteId()));
+        if (CollUtil.isEmpty(clientSiteProducts)) {
+            return TableDataInfo.build();
+        }
+        EsPageInfo<ProductBaseVo> esPageInfo = productEsMapper.pageQuery(new LambdaEsQueryWrapper<>(ProductBaseVo.class)
+                .in(ProductBaseVo::getId, clientSiteProducts.stream().map(ClientSiteProduct::getProductId).toList())
+            , pageQuery.getPageNum(), pageQuery.getPageSize()
+        );
+        if (CollUtil.isEmpty(esPageInfo.getList())) {
+            return TableDataInfo.build();
+        }
+        esPageInfo.getList().forEach(productBaseVo -> {
+            clientSiteProducts.stream()
+                .filter(clientSiteProduct -> clientSiteProduct.getProductId().equals(productBaseVo.getId()))
+                .findFirst()
+                .ifPresent(clientSiteProduct -> {
+                    productBaseVo.setAgreementPrice(clientSiteProduct.getAgreementPrice());
+                });
+        });
+        TableDataInfo tableDataInfo = new TableDataInfo();
+        tableDataInfo.setRows(esPageInfo.getList());
+        tableDataInfo.setTotal(esPageInfo.getTotal());
+        return tableDataInfo;
+    }
+
+    /**
+     * 导出客户站点产品数据
+     */
+    @Log(title = "客户站点产品配置", businessType = BusinessType.EXPORT)
+    @PostMapping("/exportData")
+    public void exportData(ClientSiteProductBo bo, HttpServletResponse response) {
+        // 站点下的产品
+        List<ClientSiteProduct> clientSiteProducts = clientSiteProductService.list(Wrappers.lambdaQuery(ClientSiteProduct.class)
+            .eq(ClientSiteProduct::getSiteId, bo.getSiteId()));
+
+        if (clientSiteProducts.isEmpty()) {
+            ExcelUtil.exportExcel(new ArrayList<>(), "客户站点产品配置", ClientSiteProductExportVo.class, response);
+            return;
+        }
+
+        // 产品数据
+        List<ProductBaseVo> productBaseVos = productEsMapper.selectList(new LambdaEsQueryWrapper<>(ProductBaseVo.class)
+            .in(ProductBaseVo::getId, clientSiteProducts.stream().map(ClientSiteProduct::getProductId).toList())
+        );
+
+        // 构建导出列表
+        List<ClientSiteProductExportVo> exportList = new ArrayList<>();
+        int serialNumber = 1;
+        for (ClientSiteProduct clientSiteProduct : clientSiteProducts) {
+            ProductBaseVo product = productBaseVos.stream()
+                .filter(p -> p.getId().equals(clientSiteProduct.getProductId()))
+                .findFirst()
+                .orElse(null);
+
+            if (product != null) {
+                ClientSiteProductExportVo exportVo = new ClientSiteProductExportVo();
+                exportVo.setSerialNumber(serialNumber++);
+                exportVo.setProductNo(product.getProductNo());
+                exportVo.setItemName(product.getItemName());
+                exportVo.setCategoryName(product.getCategoryName());
+                exportVo.setBrandName(product.getBrandName());
+                exportVo.setUnitName(product.getUnitName());
+                exportVo.setMarketPrice(product.getMarketPrice());
+                exportVo.setPlatformPrice(product.getMemberPrice());
+                exportVo.setMinSellingPrice(product.getMinSellingPrice());
+                exportVo.setPurchasingPrice(product.getPurchasingPrice());
+                exportVo.setAgreementPrice(clientSiteProduct.getAgreementPrice());
+                exportList.add(exportVo);
+            }
+        }
+
+        ExcelUtil.exportExcel(exportList, "客户站点产品配置", ClientSiteProductExportVo.class, response);
+    }
+
+
+    /**
+     * 导入客户站点产品配置数据
+     *
+     * @param file 导入文件
+     */
+    @Log(title = "客户站点产品配置", businessType = BusinessType.IMPORT)
+    @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
+        ExcelResult<ClientSiteProductImportVo> result = ExcelUtil.importExcel(
+            file.getInputStream(),
+            ClientSiteProductImportVo.class,
+            new ClientSiteProductImportListener(clientSiteProductService)
+        );
+        return R.ok(result.getAnalysis());
+    }
+
+    /**
+     * 获取导入模板
+     */
+    @PostMapping("/importTemplate")
+    public void importTemplate(HttpServletResponse response) {
+        ExcelUtil.exportExcel(new ArrayList<>(), "客户站点产品配置模板", ClientSiteProductImportVo.class, response);
+    }
 }

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ClientSiteSettingController.java

@@ -27,7 +27,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
  * 前端访问路由地址为:/product/siteSetting
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Validated
 @RequiredArgsConstructor

+ 101 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/SiteProductController.java

@@ -0,0 +1,101 @@
+package org.dromara.product.controller.pc;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.product.domain.ClientSite;
+import org.dromara.product.domain.ClientSiteFloor;
+import org.dromara.product.domain.vo.ClientSiteVo;
+import org.dromara.product.domain.vo.PcProductVo;
+import org.dromara.product.domain.vo.ProductBrandVo;
+import org.dromara.product.domain.vo.ProductCategoryVo;
+import org.dromara.product.service.*;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 大客户站点
+ * @author
+ * @date 2026/3/6 下午1:57
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/siteProduct")
+public class SiteProductController {
+    //站点主体
+    private final IClientSiteService clientSiteService;
+    //站点配置
+    private final IClientSiteSettingService clientSiteSettingService;
+    //站点楼层
+    private final IClientSiteFloorService clientSiteFloorService;
+    //商品
+    private final IProductBaseService productBaseService;
+    //商品分类
+    private final IProductBrandService productBrandService;
+
+    /**
+    * 当前客户下的站点地址
+    * */
+    @GetMapping("/getSiteAddress")
+    public R<ClientSite> getSiteAddress(){
+        ClientSite one = clientSiteService.getOne(Wrappers.lambdaQuery(ClientSite.class)
+            .eq(ClientSite::getClientId, LoginHelper.getLoginUser().getCustomerId())
+            .eq(ClientSite::getStatus, "0")
+            .last("limit 1")
+        );
+        return R.ok(one);
+    }
+
+    /**
+    * 获取站点的商品
+    * */
+    @GetMapping("/getSiteProductList")
+    public R<List<PcProductVo>> getSiteProductList(){
+        ClientSite one = clientSiteService.getOne(Wrappers.lambdaQuery(ClientSite.class)
+            .eq(ClientSite::getClientId, LoginHelper.getLoginUser().getCustomerId())
+            .eq(ClientSite::getStatus, "0")
+            .last("limit 1")
+        );
+        List<PcProductVo> pcProductVos= productBaseService.getSiteProductList(one.getId());
+        return R.ok(pcProductVos);
+    }
+
+    /**
+    * 获取站点楼层
+    * */
+    @GetMapping("/getSiteFloorList")
+    public R<List<ClientSiteFloor>> getSiteFloorList(){
+        ClientSite one = clientSiteService.getOne(Wrappers.lambdaQuery(ClientSite.class)
+            .eq(ClientSite::getClientId, LoginHelper.getLoginUser().getCustomerId())
+            .eq(ClientSite::getStatus, "0")
+            .last("limit 1")
+        );
+        List<ClientSiteFloor> clientSiteFloors = clientSiteFloorService.list(Wrappers.lambdaQuery(ClientSiteFloor.class)
+            .eq(ClientSiteFloor::getSiteId, one.getId())
+            .eq(ClientSiteFloor::getIsShow, "1")
+        );
+        return R.ok(clientSiteFloors);
+    }
+
+    /**
+    * 获取站点楼层的商品
+    * */
+    @GetMapping("/getSiteFloorProductList")
+    public R<List<PcProductVo>> getSiteFloorProductList(Long floorId){
+        return R.ok(productBaseService.getSiteFloorProductList(floorId));
+    }
+
+    /**
+    * 获取站点楼层的品牌
+    * */
+    @GetMapping("/getSiteFloorBrandList")
+    public R<List<ProductBrandVo>> getSiteFloorBrandList(Long floorId){
+        return R.ok(productBrandService.getSiteFloorBrandList(floorId));
+    }
+}

+ 2 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSite.java

@@ -13,7 +13,7 @@ import java.io.Serial;
  * 客户站点配置对象 client_site
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -117,7 +117,7 @@ public class ClientSite extends TenantEntity {
     /**
      * 协议文件路径
      */
-    private String protocolfile;
+    private String protocolFile;
 
     /**
      * 状态(0正常 1停用)

+ 76 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSiteChannelPage.java

@@ -0,0 +1,76 @@
+package org.dromara.product.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 频道页面配置对象 client_site_channel_page
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("client_site_channel_page")
+public class ClientSiteChannelPage extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID,自增
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户编号
+     */
+    private String clientNo;
+
+    /**
+     * 客户id
+     */
+    private Long clientId;
+
+    /**
+     * 简称
+     */
+    private String shortName;
+
+    /**
+     * 频道名称
+     */
+    private String channelName;
+
+    /**
+     * 频道类型
+     */
+    private String channelType;
+
+    /**
+     * 排序序号
+     */
+    private Long serial;
+
+    /**
+     * 副标题
+     */
+    private String subTitle;
+
+    /**
+     * 图片路径或URL
+     */
+    private String pic;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+
+}

+ 87 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSiteFloor.java

@@ -0,0 +1,87 @@
+package org.dromara.product.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 客户站点楼层主对象 client_site_floor
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("client_site_floor")
+public class ClientSiteFloor extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+
+    /**
+     * 楼层名称
+     */
+    private String name;
+
+    /**
+     * 楼层图片
+     */
+    private String imageUrl;
+
+    /**
+     * 链接地址
+     */
+    private String link;
+
+    /**
+     * 品牌编号集合
+     */
+    private String brandNos;
+
+    /**
+     * 排序
+     */
+    private Long sort;
+
+    /**
+     * 是否显示(0否 1是)
+     */
+    private String isShow;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 82 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSiteFloorLink.java

@@ -0,0 +1,82 @@
+package org.dromara.product.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 客户站点楼层关联对象 client_site_floor_link
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("client_site_floor_link")
+public class ClientSiteFloorLink extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 楼层ID
+     */
+    private Long floorId;
+
+    /**
+     * 类型(1商品 2品牌)
+     */
+    private Long type;
+
+    /**
+     * 商品编号
+     */
+    private String productNo;
+
+    /**
+     * 品牌编号
+     */
+    private String brandNo;
+
+    /**
+     * 商品ID
+     */
+    private Long productId;
+
+    /**
+     * 品牌id
+     */
+    private Long brandId;
+
+    /**
+     * 排序
+     */
+    private Long sort;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 8 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSiteProduct.java

@@ -6,12 +6,13 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 
 import java.io.Serial;
+import java.math.BigDecimal;
 
 /**
  * 客户站点产品配置对象 client_site_product
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -27,6 +28,11 @@ public class ClientSiteProduct extends TenantEntity {
     @TableId(value = "id")
     private Long id;
 
+    /**
+     * 站点Id
+     */
+    private Long siteId;
+
     /**
      * 客户编号
      */
@@ -75,7 +81,7 @@ public class ClientSiteProduct extends TenantEntity {
     /**
      * 协议价格(字符串形式,可能含格式或货币符号)
      */
-    private String agreementprice;
+    private BigDecimal agreementPrice;
 
     /**
      * 状态(0正常 1停用)

+ 5 - 10
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ClientSiteSetting.java

@@ -1,6 +1,6 @@
 package org.dromara.product.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;
@@ -15,12 +15,12 @@ import java.io.Serial;
  * 客户站点设置对象 client_site_setting
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("client_site_setting")
-public class ClientSiteSetting extends BaseEntity {
+public class ClientSiteSetting extends TenantEntity {
 
     @Serial
     private static final long serialVersionUID = 1L;
@@ -117,14 +117,9 @@ public class ClientSiteSetting extends BaseEntity {
     private String announcementContent;
 
     /**
-     * 创建时间
+     * 状态(0正常 1停用)
      */
-    private Date created;
-
-    /**
-     * 最后修改时间
-     */
-    private Date modify;
+    private String status;
 
 
 }

+ 2 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteBo.java

@@ -15,7 +15,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
  * 客户站点配置业务对象 client_site
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -131,7 +131,7 @@ public class ClientSiteBo extends BaseEntity {
      * 协议文件路径
      */
     //@NotBlank(message = "协议文件路径不能为空", groups = { AddGroup.class, EditGroup.class })
-    private String protocolfile;
+    private String protocolFile;
 
     /**
      * 状态(0正常 1停用)

+ 82 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteChannelPageBo.java

@@ -0,0 +1,82 @@
+package org.dromara.product.domain.bo;
+
+import org.dromara.product.domain.ClientSiteChannelPage;
+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.*;
+
+/**
+ * 频道页面配置业务对象 client_site_channel_page
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = ClientSiteChannelPage.class, reverseConvertGenerate = false)
+public class ClientSiteChannelPageBo extends BaseEntity {
+
+    /**
+     * 主键ID,自增
+     */
+    private Long id;
+
+    /**
+     * 客户编号
+     */
+    //@NotBlank(message = "客户编号不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String clientNo;
+
+    /**
+     * 客户id
+     */
+    //@NotNull(message = "客户id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long clientId;
+
+    /**
+     * 简称
+     */
+    //@NotBlank(message = "简称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String shortName;
+
+    /**
+     * 频道名称
+     */
+    //@NotBlank(message = "频道名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String channelName;
+
+    /**
+     * 频道类型
+     */
+    //@NotBlank(message = "频道类型不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String channelType;
+
+    /**
+     * 排序序号
+     */
+    private Long serial;
+
+    /**
+     * 副标题
+     */
+    //@NotBlank(message = "副标题不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String subTitle;
+
+    /**
+     * 图片路径或URL
+     */
+    //@NotBlank(message = "图片路径或URL不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String pic;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    //@NotBlank(message = "状态(0正常 1停用)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String status;
+
+
+}

+ 89 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteFloorBo.java

@@ -0,0 +1,89 @@
+package org.dromara.product.domain.bo;
+
+import org.dromara.product.domain.ClientSiteFloor;
+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.*;
+
+/**
+ * 客户站点楼层主业务对象 client_site_floor
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = ClientSiteFloor.class, reverseConvertGenerate = false)
+public class ClientSiteFloorBo extends BaseEntity {
+
+    /**
+     * ID
+     */
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    //@NotNull(message = "站点id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long siteId;
+
+    /**
+     * 客户id
+     */
+    //@NotNull(message = "客户id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long customerId;
+
+    /**
+     * 楼层名称
+     */
+    //@NotBlank(message = "楼层名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String name;
+
+    /**
+     * 楼层图片
+     */
+    //@NotBlank(message = "楼层图片不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String imageUrl;
+
+    /**
+     * 链接地址
+     */
+    //@NotBlank(message = "链接地址不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String link;
+
+    /**
+     * 品牌编号集合
+     */
+    //@NotBlank(message = "品牌编号集合不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String brandNos;
+
+    /**
+     * 排序
+     */
+    //@NotNull(message = "排序不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long sort;
+
+    /**
+     * 是否显示(0否 1是)
+     */
+    //@NotBlank(message = "是否显示(0否 1是)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String isShow;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    //@NotBlank(message = "状态(0正常 1停用)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String status;
+
+    /**
+     * 备注
+     */
+    //@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String remark;
+
+
+}

+ 82 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteFloorLinkBo.java

@@ -0,0 +1,82 @@
+package org.dromara.product.domain.bo;
+
+import org.dromara.product.domain.ClientSiteFloorLink;
+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.*;
+
+/**
+ * 客户站点楼层关联业务对象 client_site_floor_link
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = ClientSiteFloorLink.class, reverseConvertGenerate = false)
+public class ClientSiteFloorLinkBo extends BaseEntity {
+
+    /**
+     * ID
+     */
+    private Long id;
+
+    /**
+     * 楼层ID
+     */
+    private Long floorId;
+
+    /**
+     * 类型(1商品 2品牌)
+     */
+    //@NotNull(message = "类型(1商品 2品牌)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long type;
+
+    /**
+     * 商品编号
+     */
+    //@NotBlank(message = "商品编号不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String productNo;
+
+    /**
+     * 品牌编号
+     */
+    //@NotBlank(message = "品牌编号不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String brandNo;
+
+    /**
+     * 商品ID
+     */
+    //@NotNull(message = "商品ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long productId;
+
+    /**
+     * 品牌id
+     */
+    //@NotNull(message = "品牌id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long brandId;
+
+    /**
+     * 排序
+     */
+    //@NotNull(message = "排序不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long sort;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    //@NotBlank(message = "状态(0正常 1停用)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String status;
+
+    /**
+     * 备注
+     */
+    //@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String remark;
+
+
+}

+ 9 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteProductBo.java

@@ -9,11 +9,13 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import jakarta.validation.constraints.*;
 
+import java.math.BigDecimal;
+
 /**
  * 客户站点产品配置业务对象 client_site_product
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -25,6 +27,11 @@ public class ClientSiteProductBo extends BaseEntity {
      */
     private Long id;
 
+    /**
+     * 站点Id
+     */
+    private Long siteId;
+
     /**
      * 客户编号
      */
@@ -78,7 +85,7 @@ public class ClientSiteProductBo extends BaseEntity {
      * 协议价格(字符串形式,可能含格式或货币符号)
      */
     //@NotBlank(message = "协议价格(字符串形式,可能含格式或货币符号)不能为空", groups = { AddGroup.class, EditGroup.class })
-    private String agreementprice;
+    private BigDecimal agreementPrice;
 
     /**
      * 状态(0正常 1停用)

+ 4 - 9
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ClientSiteSettingBo.java

@@ -17,7 +17,7 @@ import org.dromara.common.translation.constant.TransConstant;
  * 客户站点设置业务对象 client_site_setting
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -128,15 +128,10 @@ public class ClientSiteSettingBo extends BaseEntity {
     private String announcementContent;
 
     /**
-     * 创建时间
+     * 状态(0正常 1停用)
      */
-    private Date created;
-
-    /**
-     * 最后修改时间
-     */
-    //@NotNull(message = "最后修改时间不能为空", groups = { AddGroup.class, EditGroup.class })
-    private Date modify;
+    //@NotBlank(message = "状态(0正常 1停用)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String status;
 
 
 }

+ 5 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProductBaseBo.java

@@ -348,5 +348,10 @@ public class ProductBaseBo extends BaseEntity {
      * */
     private String imageUrl;
 
+    /**
+    * 站点id
+    * */
+    private Long siteId;
+
 
 }

+ 93 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteChannelPageVo.java

@@ -0,0 +1,93 @@
+package org.dromara.product.domain.vo;
+
+import org.dromara.product.domain.ClientSiteChannelPage;
+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;
+
+
+
+/**
+ * 频道页面配置视图对象 client_site_channel_page
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ClientSiteChannelPage.class)
+public class ClientSiteChannelPageVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID,自增
+     */
+    @ExcelProperty(value = "主键ID,自增")
+    private Long id;
+
+    /**
+     * 客户编号
+     */
+    @ExcelProperty(value = "客户编号")
+    private String clientNo;
+
+    /**
+     * 客户id
+     */
+    @ExcelProperty(value = "客户id")
+    private Long clientId;
+
+    /**
+     * 简称
+     */
+    @ExcelProperty(value = "简称")
+    private String shortName;
+
+    /**
+     * 频道名称
+     */
+    @ExcelProperty(value = "频道名称")
+    private String channelName;
+
+    /**
+     * 频道类型
+     */
+    @ExcelProperty(value = "频道类型")
+    private String channelType;
+
+    /**
+     * 排序序号
+     */
+    @ExcelProperty(value = "排序序号")
+    private Long serial;
+
+    /**
+     * 副标题
+     */
+    @ExcelProperty(value = "副标题")
+    private String subTitle;
+
+    /**
+     * 图片路径或URL
+     */
+    @ExcelProperty(value = "图片路径或URL")
+    private String pic;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+
+}

+ 94 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteFloorLinkVo.java

@@ -0,0 +1,94 @@
+package org.dromara.product.domain.vo;
+
+import org.dromara.product.domain.ClientSiteFloorLink;
+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;
+
+
+
+/**
+ * 客户站点楼层关联视图对象 client_site_floor_link
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ClientSiteFloorLink.class)
+public class ClientSiteFloorLinkVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ExcelProperty(value = "ID")
+    private Long id;
+
+    /**
+     * 楼层ID
+     */
+    @ExcelProperty(value = "楼层ID")
+    private Long floorId;
+
+    /**
+     * 类型(1商品 2品牌)
+     */
+    @ExcelProperty(value = "类型", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "1=商品,2=品牌")
+    private Long type;
+
+    /**
+     * 商品编号
+     */
+    @ExcelProperty(value = "商品编号")
+    private String productNo;
+
+    /**
+     * 品牌编号
+     */
+    @ExcelProperty(value = "品牌编号")
+    private String brandNo;
+
+    /**
+     * 商品ID
+     */
+    @ExcelProperty(value = "商品ID")
+    private Long productId;
+
+    /**
+     * 品牌id
+     */
+    @ExcelProperty(value = "品牌id")
+    private Long brandId;
+
+    /**
+     * 排序
+     */
+    @ExcelProperty(value = "排序")
+    private Long sort;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 100 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteFloorVo.java

@@ -0,0 +1,100 @@
+package org.dromara.product.domain.vo;
+
+import org.dromara.product.domain.ClientSiteFloor;
+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;
+
+
+
+/**
+ * 客户站点楼层主视图对象 client_site_floor
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ClientSiteFloor.class)
+public class ClientSiteFloorVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ExcelProperty(value = "ID")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 客户id
+     */
+    @ExcelProperty(value = "客户id")
+    private Long customerId;
+
+    /**
+     * 楼层名称
+     */
+    @ExcelProperty(value = "楼层名称")
+    private String name;
+
+    /**
+     * 楼层图片
+     */
+    @ExcelProperty(value = "楼层图片")
+    private String imageUrl;
+
+    /**
+     * 链接地址
+     */
+    @ExcelProperty(value = "链接地址")
+    private String link;
+
+    /**
+     * 品牌编号集合
+     */
+    @ExcelProperty(value = "品牌编号集合")
+    private String brandNos;
+
+    /**
+     * 排序
+     */
+    @ExcelProperty(value = "排序")
+    private Long sort;
+
+    /**
+     * 是否显示(0否 1是)
+     */
+    @ExcelProperty(value = "是否显示", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=否,1=是")
+    private String isShow;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 33 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteProductImportVo.java

@@ -0,0 +1,33 @@
+package org.dromara.product.domain.vo;
+
+import cn.idev.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 客户站点产品配置导入 VO
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Data
+public class ClientSiteProductImportVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 商品编号
+     */
+    @ExcelProperty(value = "商品编号")
+    private String productNo;
+
+    /**
+     * 协议价格
+     */
+    @ExcelProperty(value = "协议价")
+    private BigDecimal agreementPrice;
+}

+ 8 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteProductVo.java

@@ -10,6 +10,7 @@ import lombok.Data;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.Date;
 
 
@@ -18,7 +19,7 @@ import java.util.Date;
  * 客户站点产品配置视图对象 client_site_product
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Data
 @ExcelIgnoreUnannotated
@@ -34,6 +35,11 @@ public class ClientSiteProductVo implements Serializable {
     @ExcelProperty(value = "主键ID,自增")
     private Long id;
 
+    /**
+     * 站点Id
+     */
+    private Long siteId;
+
     /**
      * 客户编号
      */
@@ -98,7 +104,7 @@ public class ClientSiteProductVo implements Serializable {
      */
     @ExcelProperty(value = "协议价格", converter = ExcelDictConvert.class)
     @ExcelDictFormat(readConverterExp = "字=符串形式,可能含格式或货币符号")
-    private String agreementprice;
+    private BigDecimal agreementPrice;
 
     /**
      * 状态(0正常 1停用)

+ 5 - 10
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteSettingVo.java

@@ -22,7 +22,7 @@ import java.util.Date;
  * 客户站点设置视图对象 client_site_setting
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Data
 @ExcelIgnoreUnannotated
@@ -148,16 +148,11 @@ public class ClientSiteSettingVo implements Serializable {
     private String announcementContent;
 
     /**
-     * 创建时间
+     * 状态(0正常 1停用)
      */
-    @ExcelProperty(value = "创建时间")
-    private Date created;
-
-    /**
-     * 最后修改时间
-     */
-    @ExcelProperty(value = "最后修改时间")
-    private Date modify;
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
 
 
 }

+ 2 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ClientSiteVo.java

@@ -20,7 +20,7 @@ import java.util.Date;
  * 客户站点配置视图对象 client_site
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Data
 @ExcelIgnoreUnannotated
@@ -148,7 +148,7 @@ public class ClientSiteVo implements Serializable {
      * 协议文件路径
      */
     @ExcelProperty(value = "协议文件路径")
-    private String protocolfile;
+    private String protocolFile;
 
     /**
      * 状态(0正常 1停用)

+ 9 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductBaseVo.java

@@ -475,4 +475,13 @@ public class ProductBaseVo implements Serializable {
      * 推送状态 0未推送,1已推送
      */
     private Long pushStatus;
+
+    /**
+    * 协议价
+    * */
+    private BigDecimal agreementPrice;
+    /**
+    * 创建时间
+    * */
+    private Date createTime;
 }

+ 133 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/listener/ClientSiteProductImportListener.java

@@ -0,0 +1,133 @@
+package org.dromara.product.listener;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.idev.excel.context.AnalysisContext;
+import cn.idev.excel.event.AnalysisEventListener;
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.ValidatorUtils;
+import org.dromara.common.excel.core.ExcelListener;
+import org.dromara.common.excel.core.ExcelResult;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.product.domain.bo.ClientSiteProductBo;
+import org.dromara.product.domain.vo.ClientSiteProductImportVo;
+import org.dromara.product.domain.vo.ClientSiteProductVo;
+import org.dromara.product.service.IClientSiteProductService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+/**
+ * 客户站点产品配置导入监听器
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Slf4j
+public class ClientSiteProductImportListener extends AnalysisEventListener<ClientSiteProductImportVo> implements ExcelListener<ClientSiteProductImportVo> {
+
+    private final IClientSiteProductService clientSiteProductService;
+
+    private int successNum = 0;
+    private int failureNum = 0;
+    private final StringBuilder successMsg = new StringBuilder();
+    private final StringBuilder failureMsg = new StringBuilder();
+
+    public ClientSiteProductImportListener() {
+        this.clientSiteProductService = null;
+    }
+
+    public ClientSiteProductImportListener(IClientSiteProductService clientSiteProductService) {
+        this.clientSiteProductService = clientSiteProductService;
+    }
+
+    @Override
+    public void invoke(ClientSiteProductImportVo importVo, AnalysisContext context) {
+        try {
+            // 校验必填字段
+            if (ObjectUtil.isEmpty(importVo.getProductNo())) {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(context.readRowHolder().getRowIndex() + 1).append(" 行,商品编号不能为空");
+                return;
+            }
+
+            if (ObjectUtil.isEmpty(importVo.getAgreementPrice())) {
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(context.readRowHolder().getRowIndex() + 1).append(" 行,协议价不能为空");
+                return;
+            }
+
+            // 根据商品编号查询是否已存在
+            ClientSiteProductBo queryBo = new ClientSiteProductBo();
+            queryBo.setProductNo(importVo.getProductNo());
+            List<ClientSiteProductVo> existingList = clientSiteProductService.queryList(queryBo);
+
+            if (ObjectUtil.isNotEmpty(existingList)) {
+                // 如果已存在,则更新
+                ClientSiteProductVo existing = existingList.get(0);
+                ClientSiteProductBo updateBo = new ClientSiteProductBo();
+                updateBo.setId(existing.getId());
+                updateBo.setAgreementPrice(importVo.getAgreementPrice());
+                ValidatorUtils.validate(updateBo);
+                updateBo.setUpdateBy(LoginHelper.getUserId());
+                clientSiteProductService.updateByBo(updateBo);
+                successNum++;
+                successMsg.append("<br/>").append(successNum).append("、商品编号 ").append(importVo.getProductNo()).append(" 更新成功");
+            } else {
+                // 如果不存在,则新增
+                ClientSiteProductBo insertBo = new ClientSiteProductBo();
+                insertBo.setProductNo(importVo.getProductNo());
+                insertBo.setAgreementPrice(importVo.getAgreementPrice());
+                ValidatorUtils.validate(insertBo);
+                insertBo.setCreateBy(LoginHelper.getUserId());
+                clientSiteProductService.insertByBo(insertBo);
+                successNum++;
+                successMsg.append("<br/>").append(successNum).append("、商品编号 ").append(importVo.getProductNo()).append(" 导入成功");
+            }
+        } catch (Exception e) {
+            failureNum++;
+            String msg = "<br/>" + failureNum + "、商品编号 " + importVo.getProductNo() + " 导入失败:";
+            String message = e.getMessage();
+            if (e instanceof ConstraintViolationException cvException) {
+                message = StreamUtils.join(cvException.getConstraintViolations(), ConstraintViolation::getMessage, ", ");
+            }
+            failureMsg.append(msg).append(message);
+            log.error(msg, e);
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext context) {
+
+    }
+
+    @Override
+    public ExcelResult<ClientSiteProductImportVo> getExcelResult() {
+        return new ExcelResult<ClientSiteProductImportVo>() {
+
+            @Override
+            public String getAnalysis() {
+                if (failureNum > 0) {
+                    failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
+                    throw new ServiceException(failureMsg.toString());
+                } else {
+                    successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
+                }
+                return successMsg.toString();
+            }
+
+            @Override
+            public List<ClientSiteProductImportVo> getList() {
+                return null;
+            }
+
+            @Override
+            public List<String> getErrorList() {
+                return null;
+            }
+        };
+    }
+}

+ 15 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteChannelPageMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.product.mapper;
+
+import org.dromara.product.domain.ClientSiteChannelPage;
+import org.dromara.product.domain.vo.ClientSiteChannelPageVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 频道页面配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+public interface ClientSiteChannelPageMapper extends BaseMapperPlus<ClientSiteChannelPage, ClientSiteChannelPageVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteFloorLinkMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.product.mapper;
+
+import org.dromara.product.domain.ClientSiteFloorLink;
+import org.dromara.product.domain.vo.ClientSiteFloorLinkVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 客户站点楼层关联Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+public interface ClientSiteFloorLinkMapper extends BaseMapperPlus<ClientSiteFloorLink, ClientSiteFloorLinkVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteFloorMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.product.mapper;
+
+import org.dromara.product.domain.ClientSiteFloor;
+import org.dromara.product.domain.vo.ClientSiteFloorVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 客户站点楼层主Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+public interface ClientSiteFloorMapper extends BaseMapperPlus<ClientSiteFloor, ClientSiteFloorVo> {
+
+}

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteMapper.java

@@ -8,7 +8,7 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
  * 客户站点配置Mapper接口
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 public interface ClientSiteMapper extends BaseMapperPlus<ClientSite, ClientSiteVo> {
 

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteProductMapper.java

@@ -8,7 +8,7 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
  * 客户站点产品配置Mapper接口
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 public interface ClientSiteProductMapper extends BaseMapperPlus<ClientSiteProduct, ClientSiteProductVo> {
 

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ClientSiteSettingMapper.java

@@ -8,7 +8,7 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
  * 客户站点设置Mapper接口
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 public interface ClientSiteSettingMapper extends BaseMapperPlus<ClientSiteSetting, ClientSiteSettingVo> {
 

+ 70 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteChannelPageService.java

@@ -0,0 +1,70 @@
+package org.dromara.product.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.product.domain.ClientSiteChannelPage;
+import org.dromara.product.domain.vo.ClientSiteChannelPageVo;
+import org.dromara.product.domain.bo.ClientSiteChannelPageBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 频道页面配置Service接口
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+public interface IClientSiteChannelPageService extends IService<ClientSiteChannelPage>{
+
+    /**
+     * 查询频道页面配置
+     *
+     * @param id 主键
+     * @return 频道页面配置
+     */
+    ClientSiteChannelPageVo queryById(Long id);
+
+    /**
+     * 分页查询频道页面配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 频道页面配置分页列表
+     */
+    TableDataInfo<ClientSiteChannelPageVo> queryPageList(ClientSiteChannelPageBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的频道页面配置列表
+     *
+     * @param bo 查询条件
+     * @return 频道页面配置列表
+     */
+    List<ClientSiteChannelPageVo> queryList(ClientSiteChannelPageBo bo);
+
+    /**
+     * 新增频道页面配置
+     *
+     * @param bo 频道页面配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(ClientSiteChannelPageBo bo);
+
+    /**
+     * 修改频道页面配置
+     *
+     * @param bo 频道页面配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(ClientSiteChannelPageBo bo);
+
+    /**
+     * 校验并批量删除频道页面配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteFloorLinkService.java

@@ -0,0 +1,70 @@
+package org.dromara.product.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.product.domain.ClientSiteFloorLink;
+import org.dromara.product.domain.vo.ClientSiteFloorLinkVo;
+import org.dromara.product.domain.bo.ClientSiteFloorLinkBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 客户站点楼层关联Service接口
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+public interface IClientSiteFloorLinkService extends IService<ClientSiteFloorLink>{
+
+    /**
+     * 查询客户站点楼层关联
+     *
+     * @param id 主键
+     * @return 客户站点楼层关联
+     */
+    ClientSiteFloorLinkVo queryById(Long id);
+
+    /**
+     * 分页查询客户站点楼层关联列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户站点楼层关联分页列表
+     */
+    TableDataInfo<ClientSiteFloorLinkVo> queryPageList(ClientSiteFloorLinkBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的客户站点楼层关联列表
+     *
+     * @param bo 查询条件
+     * @return 客户站点楼层关联列表
+     */
+    List<ClientSiteFloorLinkVo> queryList(ClientSiteFloorLinkBo bo);
+
+    /**
+     * 新增客户站点楼层关联
+     *
+     * @param bo 客户站点楼层关联
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(ClientSiteFloorLinkBo bo);
+
+    /**
+     * 修改客户站点楼层关联
+     *
+     * @param bo 客户站点楼层关联
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(ClientSiteFloorLinkBo bo);
+
+    /**
+     * 校验并批量删除客户站点楼层关联信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteFloorService.java

@@ -0,0 +1,70 @@
+package org.dromara.product.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.product.domain.ClientSiteFloor;
+import org.dromara.product.domain.vo.ClientSiteFloorVo;
+import org.dromara.product.domain.bo.ClientSiteFloorBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 客户站点楼层主Service接口
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+public interface IClientSiteFloorService extends IService<ClientSiteFloor>{
+
+    /**
+     * 查询客户站点楼层主
+     *
+     * @param id 主键
+     * @return 客户站点楼层主
+     */
+    ClientSiteFloorVo queryById(Long id);
+
+    /**
+     * 分页查询客户站点楼层主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户站点楼层主分页列表
+     */
+    TableDataInfo<ClientSiteFloorVo> queryPageList(ClientSiteFloorBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的客户站点楼层主列表
+     *
+     * @param bo 查询条件
+     * @return 客户站点楼层主列表
+     */
+    List<ClientSiteFloorVo> queryList(ClientSiteFloorBo bo);
+
+    /**
+     * 新增客户站点楼层主
+     *
+     * @param bo 客户站点楼层主
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(ClientSiteFloorBo bo);
+
+    /**
+     * 修改客户站点楼层主
+     *
+     * @param bo 客户站点楼层主
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(ClientSiteFloorBo bo);
+
+    /**
+     * 校验并批量删除客户站点楼层主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteProductService.java

@@ -14,7 +14,7 @@ import java.util.List;
  * 客户站点产品配置Service接口
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 public interface IClientSiteProductService extends IService<ClientSiteProduct>{
 

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteService.java

@@ -14,7 +14,7 @@ import java.util.List;
  * 客户站点配置Service接口
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 public interface IClientSiteService extends IService<ClientSite>{
 

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IClientSiteSettingService.java

@@ -14,7 +14,7 @@ import java.util.List;
  * 客户站点设置Service接口
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 public interface IClientSiteSettingService extends IService<ClientSiteSetting>{
 

+ 10 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductBaseService.java

@@ -226,4 +226,14 @@ public interface IProductBaseService extends IService<ProductBase>{
     * PC端特价商品列表
      * */
     TableDataInfo<PcProductVo> getSpecialProductList(PcProductBo bo, PageQuery pageQuery);
+
+    /**
+    * PC端站点商品列表
+     * */
+    List<PcProductVo> getSiteProductList(Long siteId);
+
+    /**
+    * PC端站点楼层商品列表
+     * */
+    List<PcProductVo> getSiteFloorProductList(Long floorId);
 }

+ 9 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductBrandService.java

@@ -6,6 +6,7 @@ import org.dromara.product.domain.vo.ProductBrandVo;
 import org.dromara.product.domain.bo.ProductBrandBo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.product.domain.vo.ProductCategoryVo;
 
 import java.util.Collection;
 import java.util.List;
@@ -106,4 +107,12 @@ public interface IProductBrandService extends IService<ProductBrand>{
      * @return
      */
     List<ProductBrandVo> getSpecialBrandList();
+
+    /**
+     * 获取站点楼层品牌
+     *
+     * @param floorId
+     * @return
+     */
+    List<ProductBrandVo> getSiteFloorBrandList(Long floorId);
 }

+ 142 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteChannelPageServiceImpl.java

@@ -0,0 +1,142 @@
+package org.dromara.product.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.product.domain.bo.ClientSiteChannelPageBo;
+import org.dromara.product.domain.vo.ClientSiteChannelPageVo;
+import org.dromara.product.domain.ClientSiteChannelPage;
+import org.dromara.product.mapper.ClientSiteChannelPageMapper;
+import org.dromara.product.service.IClientSiteChannelPageService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 频道页面配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class ClientSiteChannelPageServiceImpl  extends ServiceImpl<ClientSiteChannelPageMapper, ClientSiteChannelPage> implements IClientSiteChannelPageService {
+
+    private final ClientSiteChannelPageMapper baseMapper;
+
+    /**
+     * 查询频道页面配置
+     *
+     * @param id 主键
+     * @return 频道页面配置
+     */
+    @Override
+    public ClientSiteChannelPageVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询频道页面配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 频道页面配置分页列表
+     */
+    @Override
+    public TableDataInfo<ClientSiteChannelPageVo> queryPageList(ClientSiteChannelPageBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<ClientSiteChannelPage> lqw = buildQueryWrapper(bo);
+        Page<ClientSiteChannelPageVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的频道页面配置列表
+     *
+     * @param bo 查询条件
+     * @return 频道页面配置列表
+     */
+    @Override
+    public List<ClientSiteChannelPageVo> queryList(ClientSiteChannelPageBo bo) {
+        LambdaQueryWrapper<ClientSiteChannelPage> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<ClientSiteChannelPage> buildQueryWrapper(ClientSiteChannelPageBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<ClientSiteChannelPage> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(ClientSiteChannelPage::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getClientNo()), ClientSiteChannelPage::getClientNo, bo.getClientNo());
+        lqw.eq(bo.getClientId() != null, ClientSiteChannelPage::getClientId, bo.getClientId());
+        lqw.like(StringUtils.isNotBlank(bo.getShortName()), ClientSiteChannelPage::getShortName, bo.getShortName());
+        lqw.like(StringUtils.isNotBlank(bo.getChannelName()), ClientSiteChannelPage::getChannelName, bo.getChannelName());
+        lqw.eq(StringUtils.isNotBlank(bo.getChannelType()), ClientSiteChannelPage::getChannelType, bo.getChannelType());
+        lqw.eq(bo.getSerial() != null, ClientSiteChannelPage::getSerial, bo.getSerial());
+        lqw.eq(StringUtils.isNotBlank(bo.getSubTitle()), ClientSiteChannelPage::getSubTitle, bo.getSubTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getPic()), ClientSiteChannelPage::getPic, bo.getPic());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ClientSiteChannelPage::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), ClientSiteChannelPage::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增频道页面配置
+     *
+     * @param bo 频道页面配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(ClientSiteChannelPageBo bo) {
+        ClientSiteChannelPage add = MapstructUtils.convert(bo, ClientSiteChannelPage.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改频道页面配置
+     *
+     * @param bo 频道页面配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(ClientSiteChannelPageBo bo) {
+        ClientSiteChannelPage update = MapstructUtils.convert(bo, ClientSiteChannelPage.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(ClientSiteChannelPage entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除频道页面配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 141 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteFloorLinkServiceImpl.java

@@ -0,0 +1,141 @@
+package org.dromara.product.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.product.domain.bo.ClientSiteFloorLinkBo;
+import org.dromara.product.domain.vo.ClientSiteFloorLinkVo;
+import org.dromara.product.domain.ClientSiteFloorLink;
+import org.dromara.product.mapper.ClientSiteFloorLinkMapper;
+import org.dromara.product.service.IClientSiteFloorLinkService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 客户站点楼层关联Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class ClientSiteFloorLinkServiceImpl  extends ServiceImpl<ClientSiteFloorLinkMapper, ClientSiteFloorLink> implements IClientSiteFloorLinkService {
+
+    private final ClientSiteFloorLinkMapper baseMapper;
+
+    /**
+     * 查询客户站点楼层关联
+     *
+     * @param id 主键
+     * @return 客户站点楼层关联
+     */
+    @Override
+    public ClientSiteFloorLinkVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询客户站点楼层关联列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户站点楼层关联分页列表
+     */
+    @Override
+    public TableDataInfo<ClientSiteFloorLinkVo> queryPageList(ClientSiteFloorLinkBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<ClientSiteFloorLink> lqw = buildQueryWrapper(bo);
+        Page<ClientSiteFloorLinkVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的客户站点楼层关联列表
+     *
+     * @param bo 查询条件
+     * @return 客户站点楼层关联列表
+     */
+    @Override
+    public List<ClientSiteFloorLinkVo> queryList(ClientSiteFloorLinkBo bo) {
+        LambdaQueryWrapper<ClientSiteFloorLink> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<ClientSiteFloorLink> buildQueryWrapper(ClientSiteFloorLinkBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<ClientSiteFloorLink> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(ClientSiteFloorLink::getId);
+        lqw.eq(bo.getFloorId() != null, ClientSiteFloorLink::getFloorId, bo.getFloorId());
+        lqw.eq(bo.getType() != null, ClientSiteFloorLink::getType, bo.getType());
+        lqw.eq(StringUtils.isNotBlank(bo.getProductNo()), ClientSiteFloorLink::getProductNo, bo.getProductNo());
+        lqw.eq(StringUtils.isNotBlank(bo.getBrandNo()), ClientSiteFloorLink::getBrandNo, bo.getBrandNo());
+        lqw.eq(bo.getProductId() != null, ClientSiteFloorLink::getProductId, bo.getProductId());
+        lqw.eq(bo.getBrandId() != null, ClientSiteFloorLink::getBrandId, bo.getBrandId());
+        lqw.eq(bo.getSort() != null, ClientSiteFloorLink::getSort, bo.getSort());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ClientSiteFloorLink::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), ClientSiteFloorLink::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增客户站点楼层关联
+     *
+     * @param bo 客户站点楼层关联
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(ClientSiteFloorLinkBo bo) {
+        ClientSiteFloorLink add = MapstructUtils.convert(bo, ClientSiteFloorLink.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改客户站点楼层关联
+     *
+     * @param bo 客户站点楼层关联
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(ClientSiteFloorLinkBo bo) {
+        ClientSiteFloorLink update = MapstructUtils.convert(bo, ClientSiteFloorLink.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(ClientSiteFloorLink entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除客户站点楼层关联信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 142 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteFloorServiceImpl.java

@@ -0,0 +1,142 @@
+package org.dromara.product.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.product.domain.bo.ClientSiteFloorBo;
+import org.dromara.product.domain.vo.ClientSiteFloorVo;
+import org.dromara.product.domain.ClientSiteFloor;
+import org.dromara.product.mapper.ClientSiteFloorMapper;
+import org.dromara.product.service.IClientSiteFloorService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 客户站点楼层主Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-03-06
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class ClientSiteFloorServiceImpl  extends ServiceImpl<ClientSiteFloorMapper, ClientSiteFloor> implements IClientSiteFloorService {
+
+    private final ClientSiteFloorMapper baseMapper;
+
+    /**
+     * 查询客户站点楼层主
+     *
+     * @param id 主键
+     * @return 客户站点楼层主
+     */
+    @Override
+    public ClientSiteFloorVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询客户站点楼层主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户站点楼层主分页列表
+     */
+    @Override
+    public TableDataInfo<ClientSiteFloorVo> queryPageList(ClientSiteFloorBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<ClientSiteFloor> lqw = buildQueryWrapper(bo);
+        Page<ClientSiteFloorVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的客户站点楼层主列表
+     *
+     * @param bo 查询条件
+     * @return 客户站点楼层主列表
+     */
+    @Override
+    public List<ClientSiteFloorVo> queryList(ClientSiteFloorBo bo) {
+        LambdaQueryWrapper<ClientSiteFloor> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<ClientSiteFloor> buildQueryWrapper(ClientSiteFloorBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<ClientSiteFloor> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(ClientSiteFloor::getId);
+        lqw.eq(bo.getSiteId() != null, ClientSiteFloor::getSiteId, bo.getSiteId());
+        lqw.eq(bo.getCustomerId() != null, ClientSiteFloor::getCustomerId, bo.getCustomerId());
+        lqw.like(StringUtils.isNotBlank(bo.getName()), ClientSiteFloor::getName, bo.getName());
+        lqw.eq(StringUtils.isNotBlank(bo.getImageUrl()), ClientSiteFloor::getImageUrl, bo.getImageUrl());
+        lqw.eq(StringUtils.isNotBlank(bo.getLink()), ClientSiteFloor::getLink, bo.getLink());
+        lqw.eq(StringUtils.isNotBlank(bo.getBrandNos()), ClientSiteFloor::getBrandNos, bo.getBrandNos());
+        lqw.eq(bo.getSort() != null, ClientSiteFloor::getSort, bo.getSort());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsShow()), ClientSiteFloor::getIsShow, bo.getIsShow());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ClientSiteFloor::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), ClientSiteFloor::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增客户站点楼层主
+     *
+     * @param bo 客户站点楼层主
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(ClientSiteFloorBo bo) {
+        ClientSiteFloor add = MapstructUtils.convert(bo, ClientSiteFloor.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改客户站点楼层主
+     *
+     * @param bo 客户站点楼层主
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(ClientSiteFloorBo bo) {
+        ClientSiteFloor update = MapstructUtils.convert(bo, ClientSiteFloor.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(ClientSiteFloor entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除客户站点楼层主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 1 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteProductServiceImpl.java

@@ -25,7 +25,7 @@ import java.util.Collection;
  * 客户站点产品配置Service业务层处理
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Slf4j
 @RequiredArgsConstructor
@@ -84,7 +84,6 @@ public class ClientSiteProductServiceImpl  extends ServiceImpl<ClientSiteProduct
         lqw.eq(bo.getZsfa2View() != null, ClientSiteProduct::getZsfa2View, bo.getZsfa2View());
         lqw.eq(bo.getZsfa3View() != null, ClientSiteProduct::getZsfa3View, bo.getZsfa3View());
         lqw.eq(bo.getZsfa4View() != null, ClientSiteProduct::getZsfa4View, bo.getZsfa4View());
-        lqw.eq(StringUtils.isNotBlank(bo.getAgreementprice()), ClientSiteProduct::getAgreementprice, bo.getAgreementprice());
         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ClientSiteProduct::getStatus, bo.getStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), ClientSiteProduct::getPlatformCode, bo.getPlatformCode());
         return lqw;

+ 2 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteServiceImpl.java

@@ -25,7 +25,7 @@ import java.util.Collection;
  * 客户站点配置Service业务层处理
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Slf4j
 @RequiredArgsConstructor
@@ -91,7 +91,7 @@ public class ClientSiteServiceImpl  extends ServiceImpl<ClientSiteMapper, Client
         lqw.eq(StringUtils.isNotBlank(bo.getBackgroundColor()), ClientSite::getBackgroundColor, bo.getBackgroundColor());
         lqw.eq(bo.getIsMainsite() != null, ClientSite::getIsMainsite, bo.getIsMainsite());
         lqw.eq(StringUtils.isNotBlank(bo.getSubTitle()), ClientSite::getSubTitle, bo.getSubTitle());
-        lqw.eq(StringUtils.isNotBlank(bo.getProtocolfile()), ClientSite::getProtocolfile, bo.getProtocolfile());
+        lqw.eq(StringUtils.isNotBlank(bo.getProtocolFile()), ClientSite::getProtocolFile, bo.getProtocolFile());
         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ClientSite::getStatus, bo.getStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), ClientSite::getPlatformCode, bo.getPlatformCode());
         return lqw;

+ 3 - 3
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ClientSiteSettingServiceImpl.java

@@ -25,7 +25,7 @@ import java.util.Collection;
  * 客户站点设置Service业务层处理
  *
  * @author LionLi
- * @date 2026-03-04
+ * @date 2026-03-06
  */
 @Slf4j
 @RequiredArgsConstructor
@@ -91,8 +91,8 @@ public class ClientSiteSettingServiceImpl  extends ServiceImpl<ClientSiteSetting
         lqw.eq(bo.getEndTime() != null, ClientSiteSetting::getEndTime, bo.getEndTime());
         lqw.eq(StringUtils.isNotBlank(bo.getAnnouncementNo()), ClientSiteSetting::getAnnouncementNo, bo.getAnnouncementNo());
         lqw.eq(StringUtils.isNotBlank(bo.getAnnouncementContent()), ClientSiteSetting::getAnnouncementContent, bo.getAnnouncementContent());
-        lqw.eq(bo.getCreated() != null, ClientSiteSetting::getCreated, bo.getCreated());
-        lqw.eq(bo.getModify() != null, ClientSiteSetting::getModify, bo.getModify());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ClientSiteSetting::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), ClientSiteSetting::getPlatformCode, bo.getPlatformCode());
         return lqw;
     }
 

+ 47 - 14
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseServiceImpl.java

@@ -95,7 +95,6 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
 
     //产品基础信息Mapper
     private final ProductBaseMapper baseMapper;
-
     //库存价格与库存信息Mapper
     private final ProductPriceInventoryMapper priceInventoryMapper;
     //产品属性关联信息Mapper
@@ -118,29 +117,19 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
     private final ProductIndustrialFloorLinkMapper industrialFloorLinkMapper;
     //协议商品
     private final ProtocolProductsMapper protocolProductsMapper;
-
     private final ProductPhotosMapper photosMapper;
-
     private final ProductCategoryRecommendedLinkMapper productCategoryRecommendedLinkMapper;
-
     private final ProductCollectMapper productCollectMapper;
-
     private final ProductBrowsingHistoryMapper productBrowsingHistoryMapper;
-
     private final ProductShoppingCartMapper productShoppingCartMapper;
-
     private final ProductGiftCategoryLinkMapper productGiftCategoryLinkMapper;
-
     private final ProductGiftFloorLinkMapper productGiftFloorLinkMapper;
-
     private final ProcurementProgramProductMapper procurementProgramProductMapper;
-
     private final ProductProgramLinkMapper productProgramLinkMapper;
-
     private final ProductGiftCategoryMapper productGiftCategoryMapper;
-
     private final ProductSpecialLinkMapper productSpecialLinkMapper;
-
+    private final ClientSiteProductMapper clientSiteProductMapper;
+    private final ClientSiteFloorLinkMapper clientSiteFloorLinkMapper;
 
     private final ProductEsMapper esMapper;
 
@@ -484,7 +473,8 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
             .eq(ObjectUtil.isNotEmpty(bo.getIsSelf()), ProductBaseVo::getIsSelf, bo.getIsSelf())
             .eq(ObjectUtil.isNotEmpty(bo.getProductReviewStatus()), ProductBaseVo::getProductReviewStatus, bo.getProductReviewStatus())
             .eq(ObjectUtil.isNotEmpty(bo.getDataSource()), ProductBaseVo::getDataSource, bo.getDataSource())
-            .orderByDesc(ProductBaseVo::getId);
+//            .orderByDesc(ProductBaseVo::getCreateTime)
+            ;
         if (ObjectUtil.isNotEmpty(bo.getIds())){
             productBaseVoLambdaEsQueryWrapper.in(ProductBaseVo::getId, bo.getIds().split(","));
         }
@@ -2010,5 +2000,48 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
         }
         return TableDataInfo.build();
     }
+
+    /**
+     * PC端站点商品列表
+     *
+     * @param siteId
+     */
+    @Override
+    public List<PcProductVo> getSiteProductList(Long siteId) {
+        List<ClientSiteProductVo> clientSiteProductVos = clientSiteProductMapper.selectVoList(Wrappers.lambdaQuery(ClientSiteProduct.class).eq(ClientSiteProduct::getSiteId, siteId));
+        if (CollUtil.isNotEmpty(clientSiteProductVos)) {
+            List<ProductBaseVo> productBaseVos = esMapper.selectList(new LambdaEsQueryWrapper<ProductBaseVo>()
+                .in(ProductBaseVo::getId, clientSiteProductVos.stream().map(ClientSiteProductVo::getProductId).toList())
+            );
+            List<PcProductVo> pcProductVos = BeanUtil.copyToList(productBaseVos, PcProductVo.class);
+            pcProductVos.forEach(pcProductVo -> {
+                pcProductVo.setAgreementPrice(clientSiteProductVos.stream()
+                    .filter(o -> o.getProductId().equals(pcProductVo.getId())).findFirst().get().getAgreementPrice()); // Fixed method call
+            });
+            return pcProductVos;
+        }
+        return List.of();
+    }
+
+    /**
+     * PC端站点楼层商品列表
+     *
+     * @param floorId
+     */
+    @Override
+    public List<PcProductVo> getSiteFloorProductList(Long floorId) {
+        List<ClientSiteFloorLinkVo> clientSiteFloorLinkVos = clientSiteFloorLinkMapper.selectVoList(Wrappers.lambdaQuery(ClientSiteFloorLink.class)
+            .eq(ClientSiteFloorLink::getFloorId, floorId)
+            .eq(ClientSiteFloorLink::getType, 1)
+        );
+        if (CollUtil.isNotEmpty(clientSiteFloorLinkVos)) {
+            List<ProductBaseVo> productBaseVos = esMapper.selectList(new LambdaEsQueryWrapper<ProductBaseVo>()
+                .in(ProductBaseVo::getId, clientSiteFloorLinkVos.stream().map(ClientSiteFloorLinkVo::getProductId).toList())
+            );
+            List<PcProductVo> pcProductVos = BeanUtil.copyToList(productBaseVos, PcProductVo.class);
+            return pcProductVos;
+        }
+        return List.of();
+    }
 }
 

+ 24 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBrandServiceImpl.java

@@ -56,9 +56,13 @@ public class ProductBrandServiceImpl  extends ServiceImpl<ProductBrandMapper, Pr
 
     private final ProductSpecialLinkMapper productSpecialLinkMapper;
 
+    private final ClientSiteFloorLinkMapper clientSiteFloorLinkMapper;
+
     private final ProductEsMapper productEsMapper;
 
 
+
+
     private final ProductIndustrialFloorLinkMapper productIndustrialFloorLinkMapper;
     @Override
     public void run(ApplicationArguments args) throws Exception {
@@ -343,4 +347,24 @@ public class ProductBrandServiceImpl  extends ServiceImpl<ProductBrandMapper, Pr
             .in(ProductBrand::getId, brandIds));
         return productBrandVos;
     }
+
+    /**
+     * 获取站点楼层品牌
+     *
+     * @param floorId
+     * @return
+     */
+    @Override
+    public List<ProductBrandVo> getSiteFloorBrandList(Long floorId) {
+        List<ClientSiteFloorLinkVo> clientSiteFloorLinkVos = clientSiteFloorLinkMapper.selectVoList(Wrappers.lambdaQuery(ClientSiteFloorLink.class)
+            .eq(ClientSiteFloorLink::getFloorId, floorId)
+            .eq(ClientSiteFloorLink::getType, 2)
+        );
+        if (CollUtil.isNotEmpty(clientSiteFloorLinkVos)) {
+            return baseMapper.selectVoList(Wrappers.lambdaQuery(ProductBrand.class)
+                .in(ProductBrand::getId, clientSiteFloorLinkVos.stream().map(ClientSiteFloorLinkVo::getBrandId).toList())
+            );
+        }
+        return List.of();
+    }
 }

+ 2 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductCategoryServiceImpl.java

@@ -21,10 +21,12 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.mybatis.helper.DataBaseHelper;
 import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
+import org.dromara.product.domain.ClientSiteFloorLink;
 import org.dromara.product.domain.ProductBrand;
 import org.dromara.product.domain.ProductSpecialLink;
 import org.dromara.product.domain.vo.*;
 import org.dromara.product.esmapper.ProductEsMapper;
+import org.dromara.product.mapper.ClientSiteFloorLinkMapper;
 import org.dromara.product.mapper.ProductSpecialLinkMapper;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;

+ 7 - 0
ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ClientSiteChannelPageMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.product.mapper.ClientSiteChannelPageMapper">
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ClientSiteFloorLinkMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.product.mapper.ClientSiteFloorLinkMapper">
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ClientSiteFloorMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.product.mapper.ClientSiteFloorMapper">
+
+</mapper>

+ 1 - 0
ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductBaseMapper.xml

@@ -271,6 +271,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             b.is_new AS isNew,
             b.product_status AS productStatus,
             b.data_source AS dataSource,
+            b.create_time AS createTime,
             b.remark,
             -- 扩展表字段
             e.is_customize AS isCustomize,