From 4ccd5f799eddb87a7b19e3c65afd81100882793a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E6=AC=A7=EF=BC=88=E6=9E=97=E5=B9=B3=E5=87=A1?= =?UTF-8?q?=EF=BC=89?= Date: Fri, 10 Oct 2025 14:24:59 +0800 Subject: [PATCH] 1 --- doc/子账号功能更新说明.md | 227 ++++++++++++++++++ .../ruoyi/jarvis/domain/BatchPublishItem.java | 13 + .../domain/request/BatchPublishRequest.java | 43 +++- .../service/impl/BatchPublishServiceImpl.java | 50 ++-- .../mapper/jarvis/BatchPublishItemMapper.xml | 9 +- sql/add_sub_account_column.sql | 8 + 6 files changed, 323 insertions(+), 27 deletions(-) create mode 100644 doc/子账号功能更新说明.md create mode 100644 sql/add_sub_account_column.sql diff --git a/doc/子账号功能更新说明.md b/doc/子账号功能更新说明.md new file mode 100644 index 0000000..fb9f287 --- /dev/null +++ b/doc/子账号功能更新说明.md @@ -0,0 +1,227 @@ +# 批量发品-子账号功能更新说明 + +## 更新时间 +2025-01-10 (最后更新:2025-01-10 18:30) + +## 功能描述 +在批量发品功能中新增子账号选择功能。支持**同时选择多个主账号**,每个主账号可以**多选子账号**。系统会为每个商品×每个主账号×每个子账号创建发品任务。 + +## 前端修改 + +### 1. `ruoyi-vue/src/views/jarvis/batchPublish/index.vue` + +#### 界面改动 +- 将"目标账号"改为复选框(Checkbox),支持**同时选择多个主账号** +- 每个选中的主账号下方自动展开对应的**子账号多选下拉框** +- 子账号在首次展开或点击下拉框时自动加载 +- 支持为不同主账号选择不同的子账号组合 +- 添加加载状态提示和友好的错误提示 + +#### 数据改动 +```javascript +// 修改后的数据结构 +publishForm: { + selectedMainAccounts: [], // 选中的主账号列表 ['appid1', 'appid2'] + accountSubAccounts: { // 每个主账号对应的子账号 + 'appid1': ['子账号1', '子账号2'], + 'appid2': ['子账号3'] + } +} + +// 子账号数据 +subAccountsMap: { // 每个主账号对应的子账号选项列表 + 'appid1': [{value, label}], + 'appid2': [{value, label}] +} +loadingSubAccounts: { // 每个主账号的加载状态 + 'appid1': false, + 'appid2': true +} +``` + +#### 新增/修改方法 +- `onMainAccountsChange(selectedAccounts)`: 主账号变化时触发,清理未选中账号的数据,为新选中账号初始化数据结构 +- `loadSubAccountsForAccount(appid)`: 为指定主账号加载子账号列表(带防重复加载逻辑) + +## 后端修改 + +### 1. `BatchPublishRequest.java` +```java +// 新增内部类 +public static class AccountConfig { + private String targetAccount; // 目标ERP账号(appid) + private List subAccounts; // 该账号下的子账号列表 +} + +// 修改后的字段 +private List accountConfigs; // 账号配置列表(多个主账号+子账号) +``` + +数据结构示例: +```json +{ + "accountConfigs": [ + { + "targetAccount": "appid1", + "subAccounts": ["子账号1", "子账号2"] + }, + { + "targetAccount": "appid2", + "subAccounts": ["子账号3"] + } + ] +} +``` + +### 2. `BatchPublishItem.java` +新增字段: +```java +private String subAccount; // 子账号(会员名) +``` + +### 3. `BatchPublishServiceImpl.java` +#### batchPublish方法 +- 修改任务创建逻辑,支持多主账号配置 +- 为**每个商品 × 每个主账号 × 每个子账号**创建一条发品记录 +- 保存完整的账号配置信息到任务记录中 + +**处理逻辑:** +```java +for (ProductItem product : products) { + for (AccountConfig config : accountConfigs) { + String appid = config.getTargetAccount(); + for (String subAccount : config.getSubAccounts()) { + // 创建一条发品记录 + // 记录包含:商品信息 + 主账号(appid) + 子账号(会员名) + } + } +} +``` + +**示例:** +- 2个商品 × 2个主账号 × (每个主账号2个子账号) = 8条发品记录 + +#### publishProduct方法 +- 使用`item.getSubAccount()`作为会员名进行发品 +- 如果子账号为空,则使用通用参数中的会员名作为备选 + +### 4. `BatchPublishItemMapper.xml` +#### 修改内容 +- `resultMap`中添加`sub_account`字段映射 +- `selectBatchPublishItemVo` SQL中添加`sub_account`字段 +- `insertBatchPublishItem`中添加`sub_account`字段 +- `batchInsertBatchPublishItem`批量插入中添加`sub_account`字段 + +## 数据库修改 + +### SQL迁移脚本 +文件:`sql/add_sub_account_column.sql` + +```sql +ALTER TABLE batch_publish_item +ADD COLUMN sub_account VARCHAR(100) COMMENT '子账号(会员名)' AFTER account_remark; +``` + +## 使用流程 + +### 用户操作流程 +1. 选择线报消息并解析商品 +2. 选择要发品的商品 +3. **勾选一个或多个主账号**(支持多选) +4. 系统自动为每个选中的主账号展开子账号下拉框 +5. 在每个主账号下**选择一个或多个子账号**(支持多选) +6. 填写其他通用参数 +7. 提交批量发品 + +**界面示例:** +``` +☑ 海尔胡歌 + ↓ [子账号1, 子账号2, 子账号3] (多选下拉框) + +☑ 方案小号 + ↓ [子账号A, 子账号B] (多选下拉框) + +☐ 其他账号 +``` + +### 数据流转 +1. 前端提交数据包含: + ```javascript + { + accountConfigs: [ + { targetAccount: 'appid1', subAccounts: ['子账号1', '子账号2'] }, + { targetAccount: 'appid2', subAccounts: ['子账号A'] } + ] + } + ``` + +2. 后端处理逻辑: + - 对于每个商品 × 每个主账号配置 × 每个子账号,创建一条发品记录 + - 每条记录包含:`targetAccount`(appid)和 `subAccount`(会员名) + +3. 发品时: + - 使用`targetAccount`确定ERP账号(API密钥) + - 使用`subAccount`作为发品时的会员名 + +**发品数量计算:** +- 假设选择:2个商品、2个主账号(每个主账号选2个子账号) +- 生成发品任务数:2 × 2 × 2 = **8条发品记录** + +## 兼容性说明 + +### 向后兼容 +- 如果`subAccount`字段为空,系统会使用通用参数中的`userName`作为备选 +- 旧的发品记录不受影响,可以正常查询和显示 + +## 部署步骤 + +1. 执行数据库迁移脚本: + ```sql + source sql/add_sub_account_column.sql + ``` + +2. 重新编译并部署后端服务: + ```bash + cd ruoyi-java + mvn clean package + ``` + +3. 部署前端: + ```bash + cd ruoyi-vue + npm run build + ``` + +4. 重启服务 + +## 测试要点 + +### 基础功能测试 +1. **主账号多选**:勾选多个主账号,确认每个账号下都展开了子账号选择框 +2. **子账号加载**:确认每个主账号的子账号列表正确加载,且互不干扰 +3. **取消主账号**:取消勾选主账号时,对应的子账号数据被清理 +4. **子账号多选**:每个主账号下可以独立选择多个子账号 + +### 数据验证测试 +5. **必填验证**:未选择主账号时提示"请至少选择一个主账号" +6. **子账号验证**:选中主账号但未选子账号时,提示"请为账号XXX选择至少一个子账号" +7. **发品记录数量**:验证创建的发品记录数 = 商品数 × Σ(每个主账号的子账号数) + +### 业务功能测试 +8. **任务创建**:提交后正确创建任务,任务记录中保存完整的账号配置信息 +9. **发品明细**:查看发品明细时,主账号和子账号信息都正确显示 +10. **实际发品**:验证发品时使用了正确的主账号(API密钥)和子账号(会员名) + +### 边界情况测试 +11. **单主账号单子账号**:退化到最简单情况是否正常 +12. **多主账号多子账号**:同时选择所有主账号,每个主账号选择多个子账号 +13. **子账号为空**:某个主账号下没有子账号时的提示是否友好 +14. **网络异常**:加载子账号失败时是否有正确的错误提示 + +## 注意事项 + +1. 子账号列表通过调用`/erp/product/usernames`接口获取 +2. 该接口需要传递`appid`参数,即主账号的API Key +3. 确保ERP账号已正确授权,否则可能无法获取子账号列表 +4. 建议在生产环境部署前,先在测试环境完整测试一遍流程 + diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/BatchPublishItem.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/BatchPublishItem.java index 0d873cb..a317e92 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/BatchPublishItem.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/BatchPublishItem.java @@ -40,6 +40,10 @@ public class BatchPublishItem extends BaseEntity @Excel(name = "账号名称") private String accountRemark; + /** 子账号(会员名) */ + @Excel(name = "子账号") + private String subAccount; + /** 发品状态:0待发布 1发布中 2发布成功 3发布失败 4上架中 5已上架 6上架失败 */ @Excel(name = "发品状态", readConverterExp = "0=待发布,1=发布中,2=发布成功,3=发布失败,4=上架中,5=已上架,6=上架失败") private Integer status; @@ -118,6 +122,14 @@ public class BatchPublishItem extends BaseEntity this.accountRemark = accountRemark; } + public String getSubAccount() { + return subAccount; + } + + public void setSubAccount(String subAccount) { + this.subAccount = subAccount; + } + public Integer getStatus() { return status; } @@ -191,6 +203,7 @@ public class BatchPublishItem extends BaseEntity .append("productName", getProductName()) .append("targetAccount", getTargetAccount()) .append("accountRemark", getAccountRemark()) + .append("subAccount", getSubAccount()) .append("status", getStatus()) .append("productId", getProductId()) .append("productStatus", getProductStatus()) diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/request/BatchPublishRequest.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/request/BatchPublishRequest.java index 581ac18..70da32a 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/request/BatchPublishRequest.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/domain/request/BatchPublishRequest.java @@ -23,9 +23,9 @@ public class BatchPublishRequest { @NotEmpty(message = "商品列表不能为空") private List products; - /** 目标ERP账号列表 */ - @NotEmpty(message = "目标账号不能为空") - private List targetAccounts; + /** 账号配置列表(包含多个主账号及其子账号) */ + @NotEmpty(message = "账号配置不能为空") + private List accountConfigs; /** 通用参数 */ @NotNull(message = "通用参数不能为空") @@ -34,6 +34,35 @@ public class BatchPublishRequest { /** 延迟上架时间(秒),默认3秒 */ private Integer delaySeconds = 3; + /** + * 账号配置(主账号+子账号列表) + */ + public static class AccountConfig { + /** 目标ERP账号(appid) */ + @NotBlank(message = "目标账号不能为空") + private String targetAccount; + + /** 该账号下的子账号列表 */ + @NotEmpty(message = "子账号不能为空") + private List subAccounts; + + public String getTargetAccount() { + return targetAccount; + } + + public void setTargetAccount(String targetAccount) { + this.targetAccount = targetAccount; + } + + public List getSubAccounts() { + return subAccounts; + } + + public void setSubAccounts(List subAccounts) { + this.subAccounts = subAccounts; + } + } + public static class ProductItem { /** SKUID */ @NotBlank(message = "SKUID不能为空") @@ -292,12 +321,12 @@ public class BatchPublishRequest { this.products = products; } - public List getTargetAccounts() { - return targetAccounts; + public List getAccountConfigs() { + return accountConfigs; } - public void setTargetAccounts(List targetAccounts) { - this.targetAccounts = targetAccounts; + public void setAccountConfigs(List accountConfigs) { + this.accountConfigs = accountConfigs; } public CommonParams getCommonParams() { diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/BatchPublishServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/BatchPublishServiceImpl.java index dd05f0c..f7e6110 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/BatchPublishServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/BatchPublishServiceImpl.java @@ -256,8 +256,15 @@ public class BatchPublishServiceImpl implements IBatchPublishService @Override @Transactional public Long batchPublish(BatchPublishRequest request) { - log.info("开始批量发品任务,商品数: {}, 账号数: {}", - request.getProducts().size(), request.getTargetAccounts().size()); + // 计算总的子账号数 + int totalSubAccounts = request.getAccountConfigs().stream() + .mapToInt(config -> config.getSubAccounts().size()) + .sum(); + + log.info("开始批量发品任务,商品数: {}, 主账号数: {}, 总子账号数: {}", + request.getProducts().size(), + request.getAccountConfigs().size(), + totalSubAccounts); // 获取当前用户 SysUser currentUser = SecurityUtils.getLoginUser().getUser(); @@ -268,7 +275,8 @@ public class BatchPublishServiceImpl implements IBatchPublishService task.setOriginalMessage(request.getOriginalMessage()); task.setTotalProducts(request.getProducts().size()); task.setSelectedProducts(request.getProducts().size()); - task.setTargetAccounts(JSON.toJSONString(request.getTargetAccounts())); + // 保存账号配置信息 + task.setTargetAccounts(JSON.toJSONString(request.getAccountConfigs())); task.setStatus(0); // 待处理 task.setSuccessCount(0); task.setFailCount(0); @@ -280,21 +288,28 @@ public class BatchPublishServiceImpl implements IBatchPublishService taskMapper.insertBatchPublishTask(task); Long taskId = task.getId(); - // 创建明细记录 + // 创建明细记录 - 为每个商品×每个主账号×每个子账号创建一条记录 List items = new ArrayList<>(); + for (BatchPublishRequest.ProductItem product : request.getProducts()) { - for (String accountAppid : request.getTargetAccounts()) { - BatchPublishItem item = new BatchPublishItem(); - item.setTaskId(taskId); - item.setSkuid(product.getSkuid()); - item.setProductName(product.getProductName()); - item.setTargetAccount(accountAppid); - item.setAccountRemark(getAccountRemark(accountAppid)); - item.setStatus(0); // 待发布 - item.setPublishPrice(product.getPrice() != null ? Math.round(product.getPrice() * 100) : null); - item.setDelaySeconds(request.getDelaySeconds()); - item.setCreateTime(new Date()); - items.add(item); + for (BatchPublishRequest.AccountConfig accountConfig : request.getAccountConfigs()) { + String accountAppid = accountConfig.getTargetAccount(); + String accountRemark = getAccountRemark(accountAppid); + + for (String subAccount : accountConfig.getSubAccounts()) { + BatchPublishItem item = new BatchPublishItem(); + item.setTaskId(taskId); + item.setSkuid(product.getSkuid()); + item.setProductName(product.getProductName()); + item.setTargetAccount(accountAppid); + item.setAccountRemark(accountRemark + "-" + subAccount); + item.setSubAccount(subAccount); // 设置子账号 + item.setStatus(0); // 待发布 + item.setPublishPrice(product.getPrice() != null ? Math.round(product.getPrice() * 100) : null); + item.setDelaySeconds(request.getDelaySeconds()); + item.setCreateTime(new Date()); + items.add(item); + } } } @@ -413,7 +428,8 @@ public class BatchPublishServiceImpl implements IBatchPublishService // 2. 发布店铺(必填) PublishShop shop = new PublishShop(); - shop.setUserName(commonParams.getUserName()); + // 使用子账号作为会员名 + shop.setUserName(item.getSubAccount() != null ? item.getSubAccount() : commonParams.getUserName()); shop.setProvince(commonParams.getProvince()); shop.setCity(commonParams.getCity()); shop.setDistrict(commonParams.getDistrict()); diff --git a/ruoyi-system/src/main/resources/mapper/jarvis/BatchPublishItemMapper.xml b/ruoyi-system/src/main/resources/mapper/jarvis/BatchPublishItemMapper.xml index f4f27ba..08c1281 100644 --- a/ruoyi-system/src/main/resources/mapper/jarvis/BatchPublishItemMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/jarvis/BatchPublishItemMapper.xml @@ -11,6 +11,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -23,7 +24,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, task_id, skuid, product_name, target_account, account_remark, status, + select id, task_id, skuid, product_name, target_account, account_remark, sub_account, status, product_id, product_status, outer_id, publish_price, error_message, publish_time, delay_seconds, create_time from batch_publish_item @@ -59,6 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" product_name, target_account, account_remark, + sub_account, status, product_id, product_status, @@ -75,6 +77,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{productName}, #{targetAccount}, #{accountRemark}, + #{subAccount}, #{status}, #{productId}, #{productStatus}, @@ -89,11 +92,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" insert into batch_publish_item - (task_id, skuid, product_name, target_account, account_remark, status, publish_price, delay_seconds, create_time) + (task_id, skuid, product_name, target_account, account_remark, sub_account, status, publish_price, delay_seconds, create_time) values (#{item.taskId}, #{item.skuid}, #{item.productName}, #{item.targetAccount}, #{item.accountRemark}, - #{item.status}, #{item.publishPrice}, #{item.delaySeconds}, #{item.createTime}) + #{item.subAccount}, #{item.status}, #{item.publishPrice}, #{item.delaySeconds}, #{item.createTime}) diff --git a/sql/add_sub_account_column.sql b/sql/add_sub_account_column.sql new file mode 100644 index 0000000..212d1c8 --- /dev/null +++ b/sql/add_sub_account_column.sql @@ -0,0 +1,8 @@ +-- 添加子账号字段到批量发品明细表 +-- 执行时间: 2025-01-10 + +ALTER TABLE batch_publish_item ADD COLUMN sub_account VARCHAR(100) COMMENT '子账号(会员名)' AFTER account_remark; + +-- 为现有数据设置默认值(可选) +-- UPDATE batch_publish_item SET sub_account = '默认子账号' WHERE sub_account IS NULL; +