Explorar el Código

feat: 确认广告名称与创意名称

pudongliang hace 4 meses
padre
commit
d9b276a09e

+ 14 - 4
portal/src/views/ad-plan-conf/index.vue

@@ -109,7 +109,6 @@
             placeholder="请输入计划名称"
             clearable
           />
-          <span>作为生成广告名称的前缀用</span>
         </el-form-item>
         
         <el-form-item label="广告类型" prop="adType">
@@ -304,6 +303,8 @@
       <el-button type="primary" @click="handleReCreate">预览</el-button>
       <el-table :data="plans" 
       :preserve-expanded-content="true"
+        row-key="adgroupName"
+        :expand-row-keys="expandedRows"
       >
         <el-table-column type="expand">
         <template #default="props">
@@ -323,7 +324,8 @@
                     <span v-else>-</span>
                   </template>
                 </el-table-column>
-                <el-table-column prop="creativeText" label="创意文案" min-width="150" show-overflow-tooltip />
+                <el-table-column prop="creativeName" label="创意名称" min-width="100" show-overflow-tooltip />
+                <el-table-column prop="creativeText" label="创意文案" min-width="100" show-overflow-tooltip />
                 <el-table-column prop="brandName" label="品牌名称" width="120" />
                 <el-table-column label="品牌形象图片" width="120">
                   <template #default="{ row }">
@@ -339,7 +341,6 @@
                   </template>
                 </el-table-column>
                 <el-table-column prop="buttonText" label="按钮文案" width="120" />
-                <el-table-column label="图片ID" prop="imageId" width="100" />
                 <el-table-column label="落地页IDs" prop="pageIds" min-width="150" show-overflow-tooltip />
             </el-table>
             </div>
@@ -406,7 +407,7 @@
         border
       >
         <el-table-column type="selection" width="55" />
-        <el-table-column prop="fileUrl" label="展示" min-width="200" show-overflow-tooltip >
+        <el-table-column prop="fileUrl" label="展示" max-width="100" show-overflow-tooltip >
           <template #default="{ row }">
             <el-image
               :src="row.fileUrl"
@@ -416,6 +417,7 @@
           </template>
         </el-table-column>
         <el-table-column prop="fileType" label="类型" width="100" />
+        <el-table-column prop="originalFileName" label="文件名" width="120" show-overflow-tooltip />
         <el-table-column label="业务分类" width="120">
           <template #default="{ row }">
             <el-tag v-if="row.businessType === 1" type="success">创意</el-tag>
@@ -513,6 +515,7 @@ const editingId = ref(null)
 const conversions = ref([])
 const accountGroupList = ref([])
 const plans = ref([])
+const expandedRows = ref([])
 
 // 文件选择
 const fileSelectorVisible = ref(false)
@@ -545,6 +548,7 @@ const formData = ref({
   imageIds: '',
   pageIds: '',
   creativeFileUrls: '',
+  creativeFileNames: '',
   brandImageUrl: '',
   creativeText: '',
   brandName: '',
@@ -672,6 +676,7 @@ const handleCreate = () => {
     imageIds: '',
     pageIds: '',
     creativeFileUrls: '',
+    creativeFileNames: '',
     brandImageUrl: '',
     creativeText: '',
     brandName: '',
@@ -698,6 +703,7 @@ const handleEdit = (row) => {
     imageIds: row.imageIds || '',
     pageIds: row.pageIds || '',
     creativeFileUrls: row.creativeFileUrls || '',
+    creativeFileNames: row.creativeFileNames || '',
     brandImageUrl: row.brandImageUrl || '',
     creativeText: row.creativeText || '',
     brandName: row.brandName || '',
@@ -745,6 +751,7 @@ const handleReCreate = async () => {
   if (res.success) {
     ElMessage.success('预览成功')
     console.log(res.data)
+    expandedRows.value = [res.data[0].adgroupName]
     plans.value = res.data
   } else {
     ElMessage.error(res.message || '预览失败')
@@ -871,9 +878,12 @@ const confirmFileSelection = () => {
   }
   
   const urls = selectedFiles.value.map(file => file.fileUrl).join(',')
+  // 去除文件后缀
+  const fileNames = selectedFiles.value.map(file => file.originalFileName.split('.').slice(0, -1).join('.')).join(',')
   
   if (currentFileType.value === 'creative') {
     formData.value.creativeFileUrls = urls
+    formData.value.creativeFileNames = fileNames
   } else if (currentFileType.value === 'brand') {
     formData.value.brandImageUrl = selectedFiles.value[0].fileUrl
   }

+ 90 - 108
src/main/java/com/moka/gdtauto/controller/AdPlanConfController.java

@@ -6,14 +6,17 @@ import com.moka.gdtauto.annotation.AuthUser;
 import com.moka.gdtauto.common.Result;
 import com.moka.gdtauto.controller.vo.CreateAdPlanConfRequest;
 import com.moka.gdtauto.controller.vo.UpdateAdPlanConfRequest;
+import com.moka.gdtauto.entity.AccountGroup;
 import com.moka.gdtauto.entity.AccountGroupAccountRelationship;
 import com.moka.gdtauto.entity.AdPlanConf;
 import com.moka.gdtauto.entity.SysUser;
 import com.moka.gdtauto.entity.AdPlan;
 import com.moka.gdtauto.entity.AdPlanCreative;
+import com.moka.gdtauto.service.SysUserService;
 
 
 import com.moka.gdtauto.mapper.AccountGroupAccountRelationshipMapper;
+import com.moka.gdtauto.service.AccountGroupService;
 import com.moka.gdtauto.service.AdPlanConfService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -26,9 +29,9 @@ import java.util.List;
 
 import org.springframework.beans.BeanUtils;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestParam;
 
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 
 /**
  * 广告计划配置管理控制器
@@ -45,62 +48,21 @@ public class AdPlanConfController {
 
     private final AdPlanConfService adPlanConfService;
     private final AccountGroupAccountRelationshipMapper relationshipMapper;
+    private final SysUserService sysUserService;
+    private final AccountGroupService accountGroupService;
 
+    @Operation(summary = "预创建广告计划配置", description = "根据账户分组ID和配置ID,重新创建广告计划配置")
     @PostMapping("/reCreate")
     public Result<List<AdPlan>> reCreateAdPlanConf(
-            @RequestBody CreateAdPlanConfRequest request,
+            @RequestBody UpdateAdPlanConfRequest request,
             @AuthUser SysUser sysUser) {
         try {
-            Long accountGroupId = request.getAccountGroupId();
+            AccountGroup accountGroup = accountGroupService.getById(request.getAccountGroupId());
             List<AccountGroupAccountRelationship> relationships = relationshipMapper.selectList(
                     new LambdaQueryWrapper<AccountGroupAccountRelationship>()
-                            .eq(AccountGroupAccountRelationship::getGroupId, accountGroupId));
-            String confName = request.getName();
-            String creativeFileUrls = request.getCreativeFileUrls();
-            String[] creativeUrlArray = creativeFileUrls.split(",");
-            List<AdPlan>  plans = new ArrayList<>();
-             int i = 0;
-            for (AccountGroupAccountRelationship relationship : relationships) {
-                Long accountId = relationship.getAccountId();
-                
-                String targets = request.getTargets();
-                String sites = request.getSites();
+                            .eq(AccountGroupAccountRelationship::getGroupId, request.getAccountGroupId()));
 
-                String[] targetArray = targets.split(",");
-                String[] siteArray = sites.split(",");
-                for (String target : targetArray) {
-                    for (String site : siteArray) {
-                        i++;
-                        // 创建广告计划配置
-                        AdPlan adPlan = new AdPlan();
-                        String planName = confName + " - " + i;
-                        adPlan.setAccountId(accountId);
-                        adPlan.setAdgroupName(planName);
-                        adPlan.setAdType(request.getAdType());
-                        adPlan.setTarget(target);
-                        adPlan.setSite(site);
-                        adPlan.setConversionId(request.getConversionId());
-                        adPlan.setDramaId(request.getDramaId());
-                        adPlan.setBidAmount(request.getBidAmount());
-                        adPlan.setWxCorpid(request.getWxCorpid());
-                        plans.add(adPlan);
-                        List<AdPlanCreative> adPlanCreatives = new ArrayList<>();
-                        adPlan.setAdCreatives(adPlanCreatives);
-                        for (String creativeUrl : creativeUrlArray) {
-                            AdPlanCreative adPlanCreative = new AdPlanCreative();
-                            adPlanCreative.setCreativeFileUrl(creativeUrl);
-                            adPlanCreative.setCreativeText(request.getCreativeText());
-                            adPlanCreative.setImageId(0L);
-                            adPlanCreative.setBrandImageId(0L);
-                            adPlanCreative.setBrandName(request.getBrandName());
-                            adPlanCreative.setBrandImageUrl(request.getBrandImageUrl());
-                            adPlanCreative.setButtonText(request.getButtonText());
-                            adPlanCreative.setPageIds(request.getPageIds());
-                            adPlanCreatives.add(adPlanCreative);
-                        }
-                    }
-                }
-            }
+            List<AdPlan> plans = buildPlans(request, accountGroup, relationships);
             
             return Result.success(plans,"重新创建广告计划配置成功");
         } catch (Exception e) {
@@ -109,15 +71,84 @@ public class AdPlanConfController {
         }
     }
 
+    private List<AdPlan> buildPlans(UpdateAdPlanConfRequest request, AccountGroup accountGroup,
+            List<AccountGroupAccountRelationship> relationships) {
+        String dateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+        String accountGroupName = accountGroup.getGroupName();
+        String creativeFileUrls = request.getCreativeFileUrls();
+        String creativeFileNames = request.getCreativeFileNames();
+        String[] creativeUrlArray = creativeFileUrls.split(",");
+        String[] creativeNameArray = creativeFileNames != null ? creativeFileNames.split(",") : new String[0];
+        List<AdPlan>  plans = new ArrayList<>();
+         int i = 0;
+        for (AccountGroupAccountRelationship relationship : relationships) {
+            Long accountId = relationship.getAccountId();
+            
+            String targets = request.getTargets();
+            String sites = request.getSites();
+
+            String[] targetArray = targets.split(",");
+            String[] siteArray = sites.split(",");
+            for (String target : targetArray) {
+                for (String site : siteArray) {
+                    i++;
+                    // 创建广告计划配置
+                    // 广告名称:一般是“账户分组名”+“日期时间”+"自增编号"
+                    String planName = accountGroupName.trim() + "-" + dateTime + "-" + i;
+                    AdPlan adPlan = new AdPlan();
+                    adPlan.setAccountId(accountId);
+                    adPlan.setAdgroupName(planName);
+                    adPlan.setAdType(request.getAdType());
+                    adPlan.setTarget(target);
+                    adPlan.setSite(site);
+                    adPlan.setConversionId(request.getConversionId());
+                    adPlan.setDramaId(request.getDramaId());
+                    adPlan.setBidAmount(request.getBidAmount());
+                    adPlan.setWxCorpid(request.getWxCorpid());
+                    plans.add(adPlan);
+                    List<AdPlanCreative> adPlanCreatives = new ArrayList<>();
+                    adPlan.setAdCreatives(adPlanCreatives);
+                    int j = 0;
+                    for (String creativeUrl : creativeUrlArray) {
+                        String fileName = (j < creativeNameArray.length && creativeNameArray[j] != null && !creativeNameArray[j].isEmpty()) 
+                            ? creativeNameArray[j] 
+                            : creativeUrl.substring(creativeUrl.lastIndexOf("/") + 1);
+                        String creativeName = accountGroupName.trim() + "-" + dateTime + "-" + j + "-" + fileName;
+                        AdPlanCreative adPlanCreative = new AdPlanCreative();
+                        adPlanCreative.setCreativeFileUrl(creativeUrl);
+                        adPlanCreative.setCreativeName(creativeName);
+                        adPlanCreative.setCreativeText(request.getCreativeText());
+                        adPlanCreative.setImageId(0L);
+                        adPlanCreative.setBrandImageId(0L);
+                        adPlanCreative.setBrandName(request.getBrandName());
+                        adPlanCreative.setBrandImageUrl(request.getBrandImageUrl());
+                        adPlanCreative.setButtonText(request.getButtonText());
+                        adPlanCreative.setPageIds(request.getPageIds());
+                        adPlanCreatives.add(adPlanCreative);
+                        j++;
+                    }
+                }
+            }
+        }
+        return plans;
+    }
+
     @PostMapping("/generate-plan")
     public Result<AdPlanConf> generatePlan(
             @RequestBody UpdateAdPlanConfRequest request,
             @AuthUser SysUser sysUser) {
+        
+        SysUser user = sysUserService.getById(sysUser.getId());
+        LocalDateTime userTokenExpiresAt = user.getUserTokenExpiresAt();
+        if (userTokenExpiresAt == null || userTokenExpiresAt.isBefore(LocalDateTime.now())) {   
+            return Result.fail("实名认证已过期");
+        }
+        
         try {
-            Long accountGroupId = request.getAccountGroupId();
+            AccountGroup accountGroup = accountGroupService.getById(request.getAccountGroupId());
             List<AccountGroupAccountRelationship> relationships = relationshipMapper.selectList(
                     new LambdaQueryWrapper<AccountGroupAccountRelationship>()
-                            .eq(AccountGroupAccountRelationship::getGroupId, accountGroupId));
+                            .eq(AccountGroupAccountRelationship::getGroupId, request.getAccountGroupId()));
                             Long confId = request.getId();
             AdPlanConf adPlanConf = new AdPlanConf();
             if (confId == null) {
@@ -131,61 +162,7 @@ public class AdPlanConfController {
                 adPlanConf.setJobNumber(sysUser.getJobNumber());
                 adPlanConfService.updateAdPlanConf(adPlanConf);
             }
-
-            String confName = request.getName();
-            String creativeFileUrls = request.getCreativeFileUrls();
-            String[] creativeUrlArray = creativeFileUrls.split(",");
-            List<AdPlan>  plans = new ArrayList<>();
-             int i = 0;
-            for (AccountGroupAccountRelationship relationship : relationships) {
-                Long accountId = relationship.getAccountId();
-                
-                String targets = request.getTargets();
-                String sites = request.getSites();
-
-                String[] targetArray = targets.split(",");
-                String[] siteArray = sites.split(",");
-                for (String target : targetArray) {
-                    for (String site : siteArray) {
-                        i++;
-                        // 创建广告计划配置
-                        AdPlan adPlan = new AdPlan();
-                        adPlan.setAdPlanConfId(confId);
-                        String planName = confName + "-" + i;
-                        adPlan.setAccountId(accountId);
-                        adPlan.setAdgroupName(planName);
-                        adPlan.setAdgroupId(0L);
-                        adPlan.setAdType(request.getAdType());
-                        adPlan.setTarget(target);
-                        adPlan.setSite(site);
-                        adPlan.setConversionId(request.getConversionId());
-                        adPlan.setDramaId(request.getDramaId());
-                        adPlan.setBidAmount(request.getBidAmount());
-                        adPlan.setWxCorpid(request.getWxCorpid());
-                        plans.add(adPlan);
-                        List<AdPlanCreative> adPlanCreatives = new ArrayList<>();
-                        adPlan.setAdCreatives(adPlanCreatives);
-                        int j = 0;
-                        for (String creativeUrl : creativeUrlArray) {
-                            AdPlanCreative adPlanCreative = new AdPlanCreative();
-                            String creativeName = "测试创意-" + j++;
-                            adPlanCreative.setCreativeId(0L);
-                            adPlanCreative.setCreativeName(creativeName);
-                            adPlanCreative.setAdPlanConfId(confId);
-                            adPlanCreative.setAdgroupId(0L);
-                            adPlanCreative.setCreativeFileUrl(creativeUrl);
-                            adPlanCreative.setImageId(0L);
-                            adPlanCreative.setCreativeText(request.getCreativeText());
-                            adPlanCreative.setBrandName(request.getBrandName());
-                            adPlanCreative.setBrandImageUrl(request.getBrandImageUrl());
-                            adPlanCreative.setBrandImageId(0L);
-                            adPlanCreative.setButtonText(request.getButtonText());
-                            adPlanCreative.setPageIds(request.getPageIds());
-                            adPlanCreatives.add(adPlanCreative);
-                        }
-                    }
-                }
-            }
+            List<AdPlan> plans = buildPlans(request, accountGroup, relationships);
             
             adPlanConfService.generatePlan(plans);
 
@@ -201,7 +178,12 @@ public class AdPlanConfController {
 
 
     @GetMapping("/reGeneratePlan/{id}")
-    public Result<Void> reGeneratePlan(@PathVariable Long id) {
+    public Result<Void> reGeneratePlan(@PathVariable Long id, @AuthUser SysUser sysUser) {
+        SysUser user = sysUserService.getById(sysUser.getId());
+        LocalDateTime userTokenExpiresAt = user.getUserTokenExpiresAt();
+        if (userTokenExpiresAt == null || userTokenExpiresAt.isBefore(LocalDateTime.now())) {   
+            return Result.fail("实名认证已过期");
+        }
         adPlanConfService.asyncReGeneratePlan(id);
         return Result.success("重新生成广告计划执行中");
     }

+ 1 - 1
src/main/java/com/moka/gdtauto/controller/DashboardController.java

@@ -126,7 +126,7 @@ public class DashboardController {
     @Operation(summary = "获取最近活动", description = "获取最近的操作记录和系统事件")
     public Result<Map<String, Object>> getRecentActivities(
             @AuthUser SysUser user,
-            @RequestParam(defaultValue = "10") Integer limit) {
+            @RequestParam(defaultValue = "5") Integer limit) {
         try {
             Map<String, Object> activities = dashboardService.getRecentActivities(user.getJobNumber(), limit);
             return Result.success(activities);

+ 3 - 0
src/main/java/com/moka/gdtauto/controller/vo/CreateAdPlanConfRequest.java

@@ -49,6 +49,9 @@ public class CreateAdPlanConfRequest {
     @Schema(description = "创意图片/视频文件URL,多个用逗号分隔")
     private String creativeFileUrls;
 
+    @Schema(description = "创意图片/视频文件名,多个用逗号分隔")
+    private String creativeFileNames;
+
     @Schema(description = "品牌形象图片文件URL,单张")
     private String brandImageUrl;
 

+ 3 - 0
src/main/java/com/moka/gdtauto/controller/vo/UpdateAdPlanConfRequest.java

@@ -49,6 +49,9 @@ public class UpdateAdPlanConfRequest {
     @Schema(description = "创意图片/视频文件URL,多个用逗号分隔")
     private String creativeFileUrls;
 
+    @Schema(description = "创意图片/视频文件名,多个用逗号分隔")
+    private String creativeFileNames;
+
     @Schema(description = "品牌形象图片文件URL,单张")
     private String brandImageUrl;
 

+ 5 - 0
src/main/java/com/moka/gdtauto/entity/AdPlanConf.java

@@ -73,6 +73,11 @@ public class AdPlanConf {
     private String creativeFileUrls;
 
     /**
+     * 创意图片/视频文件名(多个用逗号分隔)
+     */
+    private String creativeFileNames;
+
+    /**
      * 品牌形象图片文件URL(从oss_file表获取,单张)
      */
     private String brandImageUrl;

+ 4 - 0
src/main/resources/sql/add_creative_file_names_to_ad_plan_conf.sql

@@ -0,0 +1,4 @@
+-- 为 ad_plan_conf 表添加 creative_file_names 字段
+ALTER TABLE ad_plan_conf 
+ADD COLUMN creative_file_names TEXT COMMENT '创意图片/视频文件名(多个用逗号分隔)' 
+AFTER creative_file_urls;