Переглянути джерело

refactor(admin): 合并电商供应商管理至供应商体系管理

- schema.sql: supply_system 新增 contact_name/contact_phone/remark 列
- DatabaseInitializer 迁移209: 补齐 supply_system 列并将 ecom_supplier 存量数据迁入
- EcomSupplierController/AdminSupplierController: 标记 @Deprecated,接口统一返回 410
- 菜单 ecomSupplier 指向 /supply-system,权限改为 system:supply
- 前端 api/admin.js 指向新接口;router 中 /ecom-supplier 重定向至 /admin/supply-system
Sisyphus 20 годин тому
батько
коміт
56d32a3f88

+ 24 - 1
cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java

@@ -8747,6 +8747,29 @@ sqls.add("INSERT IGNORE INTO health_norm_reference (dimension, gender, age_min,
 
         // 迁移225: articles 添加 growth_category 列(成长分类筛选,Article 实体已含字段,生产库缺列导致 Unknown column 'growth_category')
         ensureColumn("articles", "growth_category", "VARCHAR(50) DEFAULT NULL COMMENT '成长分类'");
+
+        // 迁移209: 将 ecom_supplier 合并至 supply_system(商品供应商管理 → 供应商体系管理统一)
+        // 1. 给 supply_system 加联系人字段
+        ensureColumn("supply_system", "contact_name", "VARCHAR(50) DEFAULT NULL COMMENT '联系人'");
+        ensureColumn("supply_system", "contact_phone", "VARCHAR(20) DEFAULT NULL COMMENT '联系电话'");
+        ensureColumn("supply_system", "remark", "VARCHAR(500) DEFAULT NULL COMMENT '备注'");
+        log.info("迁移209: supply_system 已添加 contact_name/contact_phone/remark 列");
+
+        // 2. 将 ecom_supplier 存量数据迁移到 supply_system(以平台管理员 id=1 为默认 admin)
+        try {
+            jdbcTemplate.update(
+                    "INSERT INTO supply_system (name, admin_id, settlement_period_days, platform_profit_rate, status, " +
+                            "contact_name, contact_phone, remark, created_at, updated_at) " +
+                            "SELECT name, 1, 30, 0, " +
+                            "CASE WHEN status = 1 THEN 'active' ELSE 'disabled' END, " +
+                            "contact_name, contact_phone, remark, created_at, COALESCE(updated_at, created_at) " +
+                            "FROM ecom_supplier WHERE NOT EXISTS (" +
+                            "  SELECT 1 FROM supply_system ss WHERE ss.name = ecom_supplier.name LIMIT 1)"
+            );
+            log.info("迁移209: ecom_supplier 存量数据已迁移至 supply_system");
+        } catch (Exception e) {
+            log.warn("迁移209: ecom_supplier 迁移失败(可能已存在): {}", e.getMessage());
+        }
     }
 
     private void runFullRegionDataMigrations() {
@@ -9769,7 +9792,7 @@ sqls.add("INSERT IGNORE INTO health_norm_reference (dimension, gender, age_min,
                 {"commerce", "productManage", "", "商品管理", "/product-manage", "el-icon-s-goods", "commerce:products,commerce:self", "0"},
                 {"commerce", "inventory", "", "库存管理", "/inventory", "el-icon-document", "inventory:self", "1"},
                 {"commerce", "orderManage", "", "订单管理", "/order-manage", "el-icon-s-order", "commerce:orders,order:self", "2"},
-                {"commerce", "ecomSupplier", "", "供应商管理", "/ecom-supplier", "el-icon-s-shop", "commerce:supplier", "3"},
+                {"commerce", "ecomSupplier", "", "供应商管理", "/supply-system", "el-icon-s-shop", "system:supply", "3"},
                 {"commerce", "productProfitRate", "", "产品利润率", "/product-profit-rate", "el-icon-data-line", "finance:profit-rate", "4"},
                 {"commerce", "coupon", "", "优惠券管理", "/coupon", "el-icon-ticket", "commerce:coupon", "5"},
                 {"commerce", "couponGrantLog", "", "发券记录", "/coupon-grant-log", "el-icon-document", "commerce:coupon", "6"},

+ 16 - 97
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminSupplierController.java

@@ -1,123 +1,42 @@
 package com.etotem.cfc.controller.admin;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.etotem.cfc.common.Result;
-import com.etotem.cfc.entity.EcomSupplier;
-import com.etotem.cfc.mapper.EcomSupplierMapper;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.web.bind.annotation.*;
 
-import javax.annotation.Resource;
-import java.util.Date;
-import java.util.HashMap;
 import java.util.Map;
-import com.etotem.cfc.util.SortUtil;
-import com.etotem.cfc.util.ParamUtils;
 
-@Tag(name = "管理端-电商供应商管理")
+/**
+ * @deprecated 已合并至 /api/admin/supply-system(供应商体系管理)。此接口返回 410。
+ */
+@Deprecated
+@Tag(name = "管理端-电商供应商管理(已废弃)")
 @RestController
 @RequestMapping("/api/admin/supplier")
 public class AdminSupplierController {
 
-    @Resource
-    private EcomSupplierMapper ecomSupplierMapper;
-
-    @Operation(summary = "供应商列表")
+    @Operation(summary = "【已废弃】供应商列表,请使用 /api/admin/supply-system/list")
     @PostMapping("/list")
     public Result<Map<String, Object>> list(@RequestBody Map<String, Object> params) {
-        int page = params.get("page") != null ? ((Number) params.get("page")).intValue() : 1;
-        int size = params.get("size") != null ? ((Number) params.get("size")).intValue() : 20;
-        String keyword = (String) params.get("keyword");
-
-        Page<EcomSupplier> pageParam = new Page<>(page, size);
-        LambdaQueryWrapper<EcomSupplier> wrapper = new LambdaQueryWrapper<>();
-        if (keyword != null && !keyword.isEmpty()) {
-            wrapper.like(EcomSupplier::getName, keyword);
-        }
-        wrapper.orderByDesc(EcomSupplier::getCreatedAt);
-        SortUtil.applySort(wrapper);
-        Page<EcomSupplier> result = ecomSupplierMapper.selectPage(pageParam, wrapper);
-
-        Map<String, Object> data = new HashMap<>();
-        data.put("records", result.getRecords());
-        data.put("total", result.getTotal());
-        data.put("page", page);
-        data.put("size", size);
-        return Result.success(data);
+        return Result.error(410, "该接口已废弃,请使用 /api/admin/supply-system/list");
     }
 
-    @Operation(summary = "新增供应商(兼容新旧字段契约)")
+    @Operation(summary = "【已废弃】新增供应商")
     @PostMapping("/save")
-    public Result<EcomSupplier> save(@RequestBody Map<String, Object> body) {
-        EcomSupplier supplier = new EcomSupplier();
-        applyFields(supplier, body);
-        if (supplier.getName() == null || supplier.getName().trim().isEmpty()) {
-            return Result.error("供应商名称不能为空");
-        }
-        supplier.setCreatedAt(new Date());
-        supplier.setUpdatedAt(new Date());
-        ecomSupplierMapper.insert(supplier);
-        return Result.success(supplier);
+    public Result<Map<String, Object>> save(@RequestBody Map<String, Object> body) {
+        return Result.error(410, "该接口已废弃,请使用 /api/admin/supply-system/create");
     }
 
-    @Operation(summary = "更新供应商(兼容新旧字段契约)")
+    @Operation(summary = "【已废弃】更新供应商")
     @PostMapping("/update")
-    public Result<String> update(@RequestBody Map<String, Object> body) {
-        Long id = ParamUtils.getLong(body.get("id"));
-        if (id == null) return Result.error("id不能为空");
-        EcomSupplier supplier = ecomSupplierMapper.selectById(id);
-        if (supplier == null) return Result.error("供应商不存在");
-        applyFields(supplier, body);
-        supplier.setUpdatedAt(new Date());
-        ecomSupplierMapper.updateById(supplier);
-        return Result.success("ok");
-    }
-
-    /**
-     * 字段契约兼容:前端表单提交 {phone,nickname,realName,vendorType,vendorStatus},
-     * 库表字段为 {name,contactName,contactPhone,status,remark}。新旧字段都接受,新字段优先。
-     */
-    private void applyFields(EcomSupplier supplier, Map<String, Object> body) {
-        String name = str(body, "nickname", body.get("name"));
-        if (name != null) supplier.setName(name);
-        String contactName = str(body, "realName", body.get("contactName"));
-        if (contactName != null) supplier.setContactName(contactName);
-        String contactPhone = str(body, "phone", body.get("contactPhone"));
-        if (contactPhone != null) supplier.setContactPhone(contactPhone);
-        String remark = str(body, "remark", null);
-        if (remark != null) supplier.setRemark(remark);
-        Object vendorStatus = body.get("vendorStatus") != null ? body.get("vendorStatus") : body.get("status");
-        if (vendorStatus != null) {
-            supplier.setStatus(parseStatus(vendorStatus));
-        }
-    }
-
-    private static String str(Map<String, Object> body, String key, Object fallback) {
-        Object v = body.get(key);
-        if (v == null) v = fallback;
-        return v != null ? v.toString() : null;
-    }
-
-    private static Integer parseStatus(Object v) {
-        if (v instanceof Number) return ((Number) v).intValue();
-        String s = v.toString().trim();
-        if ("active".equalsIgnoreCase(s) || "enabled".equalsIgnoreCase(s) || "1".equals(s)) return 1;
-        if ("pending".equalsIgnoreCase(s) || "disabled".equalsIgnoreCase(s) || "0".equals(s)) return 0;
-        try {
-            return Integer.valueOf(s);
-        } catch (NumberFormatException e) {
-            return 1;
-        }
+    public Result<Map<String, Object>> update(@RequestBody Map<String, Object> body) {
+        return Result.error(410, "该接口已废弃,请使用 /api/admin/supply-system/update");
     }
 
-    @Operation(summary = "删除供应商")
+    @Operation(summary = "【已废弃】删除供应商")
     @PostMapping("/delete")
-    public Result<String> delete(@RequestBody Map<String, Object> params) {
-        Long id = ParamUtils.getLong(params.get("id"));
-        if (id == null) return Result.error("id不能为空");
-        ecomSupplierMapper.deleteById(id);
-        return Result.success("ok");
+    public Result<Map<String, Object>> delete(@RequestBody Map<String, Object> params) {
+        return Result.error(410, "该接口已废弃,请使用 /api/admin/supply-system/toggle-status");
     }
 }

+ 18 - 25
cfc-backend/src/main/java/com/etotem/cfc/controller/admin/EcomSupplierController.java

@@ -1,56 +1,49 @@
 package com.etotem.cfc.controller.admin;
 
 import com.etotem.cfc.common.Result;
-import com.etotem.cfc.entity.EcomSupplier;
-import com.etotem.cfc.service.EcomSupplierService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.web.bind.annotation.*;
 
-import javax.annotation.Resource;
 import java.util.List;
 import java.util.Map;
-import com.etotem.cfc.util.ParamUtils;
 
-@Tag(name = "管理端-电商供应商")
+/**
+ * @deprecated 已合并至 /api/admin/supply-system(供应商体系管理)。此接口返回 410。
+ */
+@Deprecated
+@Tag(name = "管理端-电商供应商(已废弃)")
 @RestController
 @RequestMapping("/api/admin/ecom-supplier")
 public class EcomSupplierController {
 
-    @Resource
-    private EcomSupplierService supplierService;
-
-    @Operation(summary = "供应商列表")
+    @Operation(summary = "【已废弃】供应商列表,请使用 /api/admin/supply-system/list")
     @PostMapping("/list")
     public Result<Map<String, Object>> list(@RequestBody Map<String, Object> params) {
-        int page = params.get("page") != null ? ((Number) params.get("page")).intValue() : 1;
-        int size = params.get("size") != null ? ((Number) params.get("size")).intValue() : 20;
-        String keyword = (String) params.get("keyword");
-        return supplierService.list(page, size, keyword);
+        return Result.error(410, "该接口已废弃,请使用 /api/admin/supply-system/list");
     }
 
-    @Operation(summary = "所有供应商(下拉选择用)")
+    @Operation(summary = "【已废弃】所有供应商(下拉选择用)")
     @PostMapping("/all")
-    public Result<List<EcomSupplier>> all() {
-        return supplierService.all();
+    public Result<List<Object>> all() {
+        return Result.error(410, "该接口已废弃,请使用 /api/admin/supply-system/list-all");
     }
 
-    @Operation(summary = "创建供应商")
+    @Operation(summary = "【已废弃】创建供应商")
     @PostMapping("/save")
-    public Result<String> save(@RequestBody EcomSupplier supplier) {
-        return supplierService.save(supplier);
+    public Result<String> save(@RequestBody Object supplier) {
+        return Result.error(410, "该接口已废弃,请使用 /api/admin/supply-system/create");
     }
 
-    @Operation(summary = "更新供应商")
+    @Operation(summary = "【已废弃】更新供应商")
     @PostMapping("/update")
-    public Result<String> update(@RequestBody EcomSupplier supplier) {
-        return supplierService.update(supplier);
+    public Result<String> update(@RequestBody Object supplier) {
+        return Result.error(410, "该接口已废弃,请使用 /api/admin/supply-system/update");
     }
 
-    @Operation(summary = "删除供应商")
+    @Operation(summary = "【已废弃】删除供应商")
     @PostMapping("/delete")
     public Result<String> delete(@RequestBody Map<String, Object> params) {
-        Long id = ParamUtils.getLong(params.get("id"));
-        return supplierService.delete(id);
+        return Result.error(410, "该接口已废弃,请使用 /api/admin/supply-system/toggle-status");
     }
 }

+ 5 - 2
cfc-backend/src/main/resources/schema.sql

@@ -2662,16 +2662,19 @@ CREATE TABLE IF NOT EXISTS cart (
 
 CREATE TABLE IF NOT EXISTS supply_system (
     id BIGINT AUTO_INCREMENT PRIMARY KEY,
-    name VARCHAR(100) NOT NULL COMMENT '体系名称',
+    name VARCHAR(100) NOT NULL COMMENT '体系名称/供应商名称',
     admin_id BIGINT NOT NULL COMMENT '管理员用户ID',
     settlement_period_days INT NOT NULL DEFAULT 30 COMMENT '账期(天)',
     platform_profit_rate DECIMAL(5,2) NOT NULL DEFAULT 0 COMMENT '平台留利比例(%)',
     description TEXT COMMENT '描述',
     status VARCHAR(20) NOT NULL DEFAULT 'active' COMMENT '状态: active/disabled',
+    contact_name VARCHAR(50) COMMENT '联系人',
+    contact_phone VARCHAR(20) COMMENT '联系电话',
+    remark VARCHAR(500) COMMENT '备注',
     created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
     updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     KEY idx_admin_id (admin_id)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='供应商体系';
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='供应商体系(含电商供应商)';
 
 CREATE TABLE IF NOT EXISTS supply_system_member (
     id BIGINT AUTO_INCREMENT PRIMARY KEY,

+ 6 - 5
cfc-web/src/api/admin.js

@@ -1793,10 +1793,11 @@ export function updateCommissionConfig(data) {
   })
 }
 
-// 电商供应商管理
+// 电商供应商管理(已合并至供应商体系,接口指向 /api/admin/supply-system)
+// 保留旧函数名但指向新接口,避免前端报错
 export function getEcomSupplierList(params) {
   return request({
-    url: '/api/admin/supplier/list',
+    url: '/api/admin/supply-system/list',
     method: 'post',
     data: params
   })
@@ -1804,7 +1805,7 @@ export function getEcomSupplierList(params) {
 
 export function saveEcomSupplier(data) {
   return request({
-    url: '/api/admin/supplier/save',
+    url: '/api/admin/supply-system/create',
     method: 'post',
     data
   })
@@ -1812,7 +1813,7 @@ export function saveEcomSupplier(data) {
 
 export function updateEcomSupplier(data) {
   return request({
-    url: '/api/admin/supplier/update',
+    url: '/api/admin/supply-system/update',
     method: 'post',
     data
   })
@@ -1820,7 +1821,7 @@ export function updateEcomSupplier(data) {
 
 export function deleteEcomSupplier(id) {
   return request({
-    url: '/api/admin/supplier/delete',
+    url: '/api/admin/supply-system/toggle-status',
     method: 'post',
     data: { id }
   })

+ 3 - 3
cfc-web/src/router/index.js

@@ -826,12 +826,12 @@ const routes = [
         meta: { title: '团队成员管理', perm: 'system:base' },
         props: true
       },
-      // ========== 电商供应商管理 ==========
+      // ========== 电商供应商管理(已合并至供应商体系,路由指向 /supply-system)==========
       {
         path: 'ecom-supplier',
+        redirect: '/admin/supply-system',
         name: 'EcomSupplierManage',
-        component: () => import('@/views/admin/EcomSupplierManage'),
-        meta: { title: '电商供应商管理', perm: 'ecom:supplier' }
+        meta: { title: '电商供应商管理', perm: 'system:supply', hidden: true }
       },
       {
         path: 'badge-manage',