From d6a59d9f37202046a57289db339a170a3420a866 Mon Sep 17 00:00:00 2001 From: Vinjor Date: Tue, 5 Aug 2025 17:30:20 +0800 Subject: [PATCH] 1 --- .../base/controller/BaseSeoController.java | 88 +++++ .../ruoyi/base/controller/WebController.java | 6 - .../java/com/ruoyi/base/domain/BaseSeo.java | 59 +++ .../com/ruoyi/base/mapper/BaseSeoMapper.java | 21 ++ .../ruoyi/base/service/IBaseSeoService.java | 18 + .../base/service/impl/BaseSeoServiceImpl.java | 30 ++ .../java/com/ruoyi/base/vo/KeywordVO.java | 27 ++ .../busi/service/GoogleKeywordService.java | 95 +++-- .../com/ruoyi/constant/CompetitionEnum.java | 58 +++ .../java/com/ruoyi/constant/StrConstants.java | 9 + .../src/main/resources/application.yml | 11 +- .../src/main/resources/chengda.json | 12 +- .../resources/mapper/base/BaseSeoMapper.xml | 39 ++ .../com/ruoyi/common/config/GoogleConfig.java | 1 + dl_vue/.env.development | 2 +- dl_vue/src/api/base/seo.js | 19 + dl_vue/src/views/busi/prod/prodForm.vue | 356 ++++++++++++++---- 17 files changed, 720 insertions(+), 131 deletions(-) create mode 100644 dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/BaseSeoController.java create mode 100644 dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/domain/BaseSeo.java create mode 100644 dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/mapper/BaseSeoMapper.java create mode 100644 dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/IBaseSeoService.java create mode 100644 dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseSeoServiceImpl.java create mode 100644 dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/vo/KeywordVO.java create mode 100644 dl_admin/ruoyi-admin/src/main/java/com/ruoyi/constant/CompetitionEnum.java create mode 100644 dl_admin/ruoyi-admin/src/main/resources/mapper/base/BaseSeoMapper.xml create mode 100644 dl_vue/src/api/base/seo.js diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/BaseSeoController.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/BaseSeoController.java new file mode 100644 index 0000000..73e7437 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/BaseSeoController.java @@ -0,0 +1,88 @@ +package com.ruoyi.base.controller; + +import java.util.*; +import java.util.stream.Collectors; +import javax.servlet.http.HttpServletResponse; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.base.vo.KeywordVO; +import com.ruoyi.busi.service.GoogleKeywordService; +import com.ruoyi.common.config.GoogleConfig; +import com.ruoyi.common.utils.StringUtils; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.base.domain.BaseSeo; +import com.ruoyi.base.service.IBaseSeoService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +import static com.ruoyi.constant.StrConstants.COUNTRY; +import static com.ruoyi.constant.StrConstants.LANGUAGE; + +/** + * SEO用到的国家和语言Controller + * + * @author vinjor-m + * @date 2025-08-04 + */ +@RestController +@RequestMapping("/base/seo") +public class BaseSeoController extends BaseController { + @Autowired + private GoogleConfig googleConfig; + @Autowired + private IBaseSeoService baseSeoService; + @Autowired + private GoogleKeywordService googleKeywordService; + + /** + * 查询SEO用到的国家和语言列表 + */ + @GetMapping("/list") + public AjaxResult list() { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper().orderByAsc(BaseSeo::getSort); + List list = baseSeoService.list(queryWrapper); + List languageList = list.stream().filter(item -> LANGUAGE.equals(item.getDataType())).collect(Collectors.toList()); + List countryList = list.stream().filter(item -> COUNTRY.equals(item.getDataType())).collect(Collectors.toList()); + languageList.forEach(item->item.setTitle(item.getTitle()+"("+item.getCn()+")")); + countryList.forEach(item->item.setTitle(item.getTitle()+"("+item.getCn()+")")); + Map rtnMap = new HashMap<>(); + rtnMap.put("language", languageList); + rtnMap.put("country", countryList); + return success(rtnMap); + } + + /** + * 获取google关键词 + * + * @param language 语言 + * @param country 国家 + * @param title 关键词 + * @param url 产品预览网址 + * @return com.ruoyi.common.core.domain.AjaxResult + * @author vinjor-M + * @date 17:51 2025/8/4 + **/ + @GetMapping("/getKeywords") + public AjaxResult getKeywords(String language, String country, String title, String url) { + Map rtnMap = new HashMap<>(); + rtnMap.put("searchDown",googleConfig.getSearchDown()); + rtnMap.put("dataList",googleKeywordService.getKeywords(language, country, title, url)); + return success(rtnMap); + } +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/WebController.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/WebController.java index c4988ba..631ccef 100644 --- a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/WebController.java +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/WebController.java @@ -465,12 +465,6 @@ public class WebController extends BaseController { return R.ok(); } - @GetMapping("/test") - public R test() { - googleKeywordService.test(); - return R.ok(); - } - /** * 导航栏接口--所有分类 * @author vinjor-M diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/domain/BaseSeo.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/domain/BaseSeo.java new file mode 100644 index 0000000..8ab03dc --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/domain/BaseSeo.java @@ -0,0 +1,59 @@ +package com.ruoyi.base.domain; + +import com.ruoyi.common.annotation.Excel; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; +import com.ruoyi.common.core.domain.DlBaseEntity; + +/** + * SEO用到的国家和语言对象 dl_base_seo + * + * @author vinjor-m + * @date 2025-08-04 + */ +@TableName("dl_base_seo") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BaseSeo extends DlBaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + @TableId(type = IdType.ASSIGN_UUID) + private Long id; + + /** 数据类型(language-语言|country-国家) */ + @Excel(name = "数据类型", readConverterExp = "l=anguage-语言|country-国家") + private String dataType; + + /** 排序 */ + @Excel(name = "排序") + private Long sort; + + /** 标题 */ + @Excel(name = "标题") + private String title; + + /** 值 */ + @Excel(name = "值") + private String content; + + /** 描述 */ + @Excel(name = "描述") + private String description; + + /** 图片 */ + @Excel(name = "图片") + private String pic; + + /** 中文 */ + @Excel(name = "中文") + private String cn; + +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/mapper/BaseSeoMapper.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/mapper/BaseSeoMapper.java new file mode 100644 index 0000000..a7fd614 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/mapper/BaseSeoMapper.java @@ -0,0 +1,21 @@ +package com.ruoyi.base.mapper; + +import java.util.List; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.base.domain.BaseSeo; +import org.apache.ibatis.annotations.Param; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * SEO用到的国家和语言Mapper接口 + * + * @author vinjor-m + * @date 2025-08-04 + */ +@Mapper +public interface BaseSeoMapper extends BaseMapper +{ + IPage queryListPage(@Param("entity") BaseSeo entity, Page page); +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/IBaseSeoService.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/IBaseSeoService.java new file mode 100644 index 0000000..0d435f6 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/IBaseSeoService.java @@ -0,0 +1,18 @@ +package com.ruoyi.base.service; + +import java.util.List; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.base.domain.BaseSeo; + +/** + * SEO用到的国家和语言Service接口 + * + * @author vinjor-m + * @date 2025-08-04 + */ +public interface IBaseSeoService extends IService +{ + IPage queryListPage(BaseSeo pageReqVO, Page page); +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseSeoServiceImpl.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseSeoServiceImpl.java new file mode 100644 index 0000000..88007ed --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/service/impl/BaseSeoServiceImpl.java @@ -0,0 +1,30 @@ +package com.ruoyi.base.service.impl; + +import java.util.List; +import com.ruoyi.common.utils.DateUtils; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.base.mapper.BaseSeoMapper; +import com.ruoyi.base.domain.BaseSeo; +import com.ruoyi.base.service.IBaseSeoService; + +/** + * SEO用到的国家和语言Service业务层处理 + * + * @author vinjor-m + * @date 2025-08-04 + */ +@Service +public class BaseSeoServiceImpl extends ServiceImpl implements IBaseSeoService +{ + @Autowired + private BaseSeoMapper baseSeoMapper; + + @Override + public IPage queryListPage(BaseSeo pageReqVO, Page page) { + return baseSeoMapper.queryListPage(pageReqVO, page); + } +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/vo/KeywordVO.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/vo/KeywordVO.java new file mode 100644 index 0000000..9f01778 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/vo/KeywordVO.java @@ -0,0 +1,27 @@ +package com.ruoyi.base.vo; + +import com.ruoyi.base.domain.BasePics; +import lombok.Data; + +import java.util.List; + +/** + * 谷歌关键词规划师VO + * @author vinjor-M + * @date 17:53 2025/8/4 +**/ +@Data +public class KeywordVO { + /** + * 关键词 + **/ + private String title; + /** + * 月搜索量 + **/ + private Long searchMonth; + /** + * 竞争程度 + **/ + private String competition; +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/GoogleKeywordService.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/GoogleKeywordService.java index 39c7d41..d6eb733 100644 --- a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/GoogleKeywordService.java +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/GoogleKeywordService.java @@ -1,18 +1,14 @@ package com.ruoyi.busi.service; +import cn.hutool.core.util.StrUtil; import com.google.ads.googleads.lib.GoogleAdsClient; -import com.google.ads.googleads.v20.common.Keyword; -import com.google.ads.googleads.v20.common.KeywordAnnotations; -import com.google.ads.googleads.v20.common.KeywordConcept; -import com.google.ads.googleads.v20.enums.KeywordPlanKeywordAnnotationEnum; import com.google.ads.googleads.v20.enums.KeywordPlanNetworkEnum; -import com.google.ads.googleads.v20.enums.KeywordPlanKeywordAnnotationEnum.KeywordPlanKeywordAnnotation; import com.google.ads.googleads.v20.services.*; import com.google.auth.oauth2.GoogleCredentials; import com.google.auth.oauth2.ServiceAccountCredentials; +import com.ruoyi.base.vo.KeywordVO; import com.ruoyi.common.config.GoogleConfig; -import com.ruoyi.common.config.OssConfig; -import lombok.var; +import com.ruoyi.constant.CompetitionEnum; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -21,8 +17,6 @@ import org.springframework.util.ResourceUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.*; @Service @@ -30,7 +24,19 @@ public class GoogleKeywordService { @Autowired private GoogleConfig googleConfig; - public void test() { + /** + * 获取谷歌关键词规划师规划的关键词 + * + * @param language 语言编码 + * @param country 国家编码,多个英文逗号隔开 + * @param title 关键词,多个英文逗号分隔 + * @param url url + * @return java.util.List + * @author vinjor-M + * @date 17:55 2025/8/4 + **/ + public List getKeywords(String language, String country, String title, String url) { + List keywordList = new ArrayList<>(); try { // 1. 检查文件是否存在 File file = ResourceUtils.getFile("file:" + googleConfig.getJsonPath()); @@ -49,31 +55,42 @@ public class GoogleKeywordService { .build(); // 2. 设置参数 - List seedKeywords = Arrays.asList("TRUCK"); - // 英语 - String language = "languageConstants/1000"; - // 美国 - String geoTarget = "geoTargetConstants/2840"; - + List seedKeywords = Arrays.asList(title.split(StrUtil.COMMA)); + // 语言 + language = "languageConstants/"+language; + // 国家/地区 + List geoTargetList = new ArrayList<>(); + for (String item:country.split(StrUtil.COMMA)){ + geoTargetList.add("geoTargetConstants/"+item); + } // 3. 获取关键词提示 List keywordIdeas = generateKeywordIdeas( - googleAdsClient, googleConfig.getCustomerId(), seedKeywords, language, geoTarget); + googleAdsClient, googleConfig.getCustomerId(), seedKeywords, language, geoTargetList,url); // 4. 输出结果 for (GenerateKeywordIdeaResult idea : keywordIdeas) { // 获取关键词文本 String text = idea.getText(); + KeywordVO keywordVO = new KeywordVO(); + keywordVO.setTitle(text); // 获取关键词指标(可选) if (idea.hasKeywordIdeaMetrics()) { long avgMonthlySearches = idea.getKeywordIdeaMetrics().getAvgMonthlySearches(); String competition = String.valueOf(idea.getKeywordIdeaMetrics().getCompetition()); - System.out.println("找到的关键词文本:" + text+";月搜索量:" + avgMonthlySearches+";竞争程度:" + competition); + if(avgMonthlySearches>=googleConfig.getSearchDown()){ + //大于要求的最低月搜索量,返回 + keywordVO.setSearchMonth(avgMonthlySearches); + keywordVO.setCompetition(CompetitionEnum.getTitleByCode(competition).getTitle()); + keywordList.add(keywordVO); + } } } } catch (IOException e) { System.err.printf("初始化 Google Ads 客户端失败: %s%n", e.getMessage()); - e.printStackTrace(); } + // 倒序排列 + keywordList.sort((o1, o2) -> Long.compare(o2.getSearchMonth(), o1.getSearchMonth())); + return keywordList; } /** @@ -83,7 +100,8 @@ public class GoogleKeywordService { * @param customerId 客户ID * @param seedKeywords 种子关键词列表 * @param language 语言常量 (如 "languageConstants/1000" 表示英语) - * @param geoTarget 地理位置目标常量 (如 "geoTargetConstants/2840" 表示美国) + * @param geoTargets 地理位置目标常量 (如 "geoTargetConstants/2840" 表示美国) + * @param url 网址 * @return 关键词提示列表 * @throws IOException 如果API调用失败 */ @@ -92,24 +110,36 @@ public class GoogleKeywordService { long customerId, List seedKeywords, String language, - String geoTarget) throws IOException { - + List geoTargets,String url) throws IOException { List allKeywordIdeas = new ArrayList<>(); + //分页token String nextPageToken = null; - - KeywordAndUrlSeed seed = KeywordAndUrlSeed.newBuilder() - .addAllKeywords(seedKeywords) - .setUrl("https://www.cdtruck.com/truck/dump-truck/china-sinotruk-howo-19m3-6x4-cheap-336hp-10.html") // 提供相关 URL - .build(); + //组装关键词请求体 + KeywordAndUrlSeed urlSeed = null; + KeywordSeed seed = null; + if(StringUtils.isNotEmpty(url)){ + urlSeed = KeywordAndUrlSeed.newBuilder() + .addAllKeywords(seedKeywords) + .setUrl(url) + .build(); + }else{ + seed = KeywordSeed.newBuilder() + .addAllKeywords(seedKeywords) + .build(); + } do { try (KeywordPlanIdeaServiceClient client = googleAdsClient.getLatestVersion().createKeywordPlanIdeaServiceClient()) { GenerateKeywordIdeasRequest.Builder requestBuilder = GenerateKeywordIdeasRequest.newBuilder() .setCustomerId(Long.toString(customerId)) - .setLanguage(String.valueOf(1000)) - .addAllGeoTargetConstants(Collections.singletonList(geoTarget)) - .setKeywordPlanNetwork(KeywordPlanNetworkEnum.KeywordPlanNetwork.GOOGLE_SEARCH_AND_PARTNERS) - .setKeywordAndUrlSeed(seed); + .setLanguage(language) + .addAllGeoTargetConstants(geoTargets) + .setKeywordPlanNetwork(KeywordPlanNetworkEnum.KeywordPlanNetwork.GOOGLE_SEARCH_AND_PARTNERS); + if(StringUtils.isNotEmpty(url)){ + requestBuilder.setKeywordAndUrlSeed(urlSeed); + }else{ + requestBuilder.setKeywordSeed(seed); + } // 仅在非首次请求时设置 pageToken if (nextPageToken != null) { requestBuilder.setPageToken(nextPageToken); @@ -118,10 +148,9 @@ public class GoogleKeywordService { GenerateKeywordIdeaResponse response = client.generateKeywordIdeasCallable().call(request); allKeywordIdeas.addAll(response.getResultsList()); nextPageToken = response.getNextPageToken(); - System.out.println("分页token:"+nextPageToken); } } while (StringUtils.isNotEmpty(nextPageToken)); - System.out.println("关键词总数:"+allKeywordIdeas.size()); + System.out.println("关键词总数:" + allKeywordIdeas.size()); return allKeywordIdeas; } diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/constant/CompetitionEnum.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/constant/CompetitionEnum.java new file mode 100644 index 0000000..e58c8d8 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/constant/CompetitionEnum.java @@ -0,0 +1,58 @@ +package com.ruoyi.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 竞争程度枚举值 + * + * @author vinjor-m + */ +@AllArgsConstructor +@Getter +public enum CompetitionEnum { + /** + *UNSPECIFIED-未知 + */ + UNSPECIFIED("UNSPECIFIED","未知"), + /** + *UNKNOWN-未知 + */ + UNKNOWN("UNKNOWN","未知"), + /** + *LOW-低 + */ + LOW("LOW","低"), + /** + *MEDIUM-中 + */ + MEDIUM("MEDIUM","中"), + /** + *HIGH-高 + */ + HIGH("HIGH","高"); + + /** + * code + */ + private String code; + /** + * 标题 + */ + private String title; + /** + * 根据code返回对应的枚举 + * @author vinjor-M + * @date 14:23 2024/10/16 + * @param code code + **/ + public static CompetitionEnum getTitleByCode(String code) { + for (CompetitionEnum thisEnum : CompetitionEnum.values()) { + if (thisEnum.getCode().equalsIgnoreCase(code)) { + // 找到对应的枚举 + return thisEnum; + } + } + throw new IllegalArgumentException("无效的code:" + code); + } + } diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/constant/StrConstants.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/constant/StrConstants.java index 19f76d9..2fa5edf 100644 --- a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/constant/StrConstants.java +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/constant/StrConstants.java @@ -27,4 +27,13 @@ public class StrConstants { * 取权重最高的前N个词 */ public static final int TOP_N = 3; + + /** + * 语言 + */ + public static final String LANGUAGE = "language"; + /** + * 国家 + */ + public static final String COUNTRY = "country"; } diff --git a/dl_admin/ruoyi-admin/src/main/resources/application.yml b/dl_admin/ruoyi-admin/src/main/resources/application.yml index 72bbbb2..e374c89 100644 --- a/dl_admin/ruoyi-admin/src/main/resources/application.yml +++ b/dl_admin/ruoyi-admin/src/main/resources/application.yml @@ -153,7 +153,12 @@ aliyun: #google ads配置 google: ads: - customer-id: 4577179829 - developer-token: qwFA3dGfOGqEhSEHlCMorA - json-path: /www/wwwroot/nuxt/test.json + #经理账号id + customer-id: 3052342727 + #开发者令牌 + developer-token: 7e_-FWCPRjWc16zr8uaUDg + #服务账号秘钥文件路径 + json-path: /www/wwwroot/nuxt/chengda.json + #月搜索量下限 + search-down: 500 diff --git a/dl_admin/ruoyi-admin/src/main/resources/chengda.json b/dl_admin/ruoyi-admin/src/main/resources/chengda.json index d8ab738..13e37ae 100644 --- a/dl_admin/ruoyi-admin/src/main/resources/chengda.json +++ b/dl_admin/ruoyi-admin/src/main/resources/chengda.json @@ -1,13 +1,13 @@ { "type": "service_account", - "project_id": "chengda-466307", - "private_key_id": "c4f38952fb0922ff625a85d364543f415f93d03d", - "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCRIuvHsOaOnXv5\nlLl3R0fLrWjd8fk6tDv1bIJFpC2xfFem2rYaG1IFJVfnGgCAL7P4j6tVn0j684dL\n2wb4BRJjyK4EDYBLkugc3BWNnpt6z80f8+U39/QtDwRBJqQGvRD4LGhm5dDrAWhf\ngeiCKVC+3TGDGDwkt4JjuZQ6/GSrvX9aSaLyT5PlpYSvxH2tetb5rY6LdeAR9wS1\n0dtFD0jIxYHm96vWpe1LLhtw+28thxYeR7VFOZf6HzJLDDOt4hYbHoo+DAKaPIyC\n6+CepAcE13WWn7ooPGjh8JAGPqs2JpqR6ujFrvYXAto3UvpXSV0W6h1gRv9AD3SW\n33Te4KYzAgMBAAECggEAEu74zkCsGx+9TBZUSZSxb4csPoPyDO/1QHOK3RXpZhWA\nA8LVbbtxrD0uZfYU6aQPeNYZNl7EsQQy+rjUhGd4+i50URAH1BQSlq05XJO72b4h\nFtGE7hO5NWWXmv40+LISdCWq6v2BDx9MY+U5FT3ZjESj0GPJeMq9xk+v4DAL3AF2\nqsXsL/GhSLTyIWufIaxwUPFfumVVqjH3r9B1YqY+0Z//E/2I9W3NOSQ83JzI1osw\nQ5ybQdQ9zQptlr/kh9sb+vtgJ4+7h6RQ6Xcyy6OsW4Kg6Ho7eRTBDIytv9o7Ef+h\nVYwV6OjonAcWcbfCY2TGEO2DDJJbkZZwRby2WE5jkQKBgQDMQt/XfWCI2EVPNwpn\nl6gFY7vWcXSO+dkEloFgIpbxiJTmZTRmWPnpqqEaxUNo2KCxyuUoOCC7B+D6AdRI\nBZfxaFtQe+f71oocnWbjNtzLvW8cnZouHI1pT+HXWO84aq7fh4lkYhXsEZkhu2Ce\nV1nGjSVboe/OJ+Z9oCNVQxtlsQKBgQC15idlkFZbCR3zBDmc9LRDC1iZXyhBlSva\nT30e1M7sOO8lN2Uw825XaP4CKE70jOxL5eLkSvXALWOdeVZ79iclAoz+iE8FsLPf\nbUOWAEuUtsgyyrmkcKU/ddvtvEwsBFqZ0CxxqOCDXj+uXoGifyFLigkl3w5wvY0s\njpe1wipvIwKBgQCUvvpc5XugC8ZlSlK0X5dG3XsTTamw2Lc2BRgP1wCOwYSVRwvi\noFbV16DcatyNBHv5HSTFpiIHsVQfG6foDtK4ROOCd8jW90O6VNFxEym04K2CbC6z\n96zvDPIMrUH/lojkVMIzrM4EDEi0bMyOYlQJKA4VbZbBTQMnZq90Tpsr8QKBgQCr\nd/k9aZGuIWsFEb+JsLdY2BI+ChC1ufvrwLDO5obk8UqmR5DxUxh597QyrnK3XzzE\n00FOOUduUJst8BrRohoGbmAg9LehQpBdFu/2L/MPjjosfyP+2l079EtM0QrxF22c\nvzuWLT7vN2JKajZDyxnEzquO8rT3HAg/r29d3FoKBwKBgQCM4BNOTBT10gCPKQBx\nApULMInlweLr393rc17cJHSSLmL0z26oIfpJYVf+AbV4sLKE9HaCmwxTiR/frt9f\nEhAaOsWfprl/CFC3kcF/Vndey2v9Nlwdzl7//8c0O8ITlqt+OpK3giOUquMWuG8i\nFU9AwpseRhEp5uHZ5e1wKgsEsA==\n-----END PRIVATE KEY-----\n", - "client_email": "chengdatest@chengda-466307.iam.gserviceaccount.com", - "client_id": "108513526311014104962", + "project_id": "chengda-467707", + "private_key_id": "a9a538af8b2e1e3a41f8bc6265200a432450dd00", + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCaoBGTyINWYh5o\nFSmaGJ33q8wRIevL+GC6oqywzdyvk7in5MKpkGtKnx4yy8Cy0TSHp5yAsoXtblWV\n1TrrV7hia8IizB6QxkZQbcwwPz12shH7HN65m4lOdhsEjsSPZogYIwvDDtkXsAyl\nB+ALfYb+DZpX2aTST+1fvtTc+3PdrfxXBmBqmwJeTaQOVBk10BW+vDL9Y8TxuvHS\nYWbix/PJDQEpJFcQI/1shgiyeNkvBQJAxUHgb58EncukAD3F1W7wLLEJtE+5cnGU\nCH1KNHt+ymmZ/TJ1hdf/BvSjtHTgTYSM/ViEQZ7aTj1RZ1xueflSt2Pzqq84GMP3\nOJaCgcObAgMBAAECggEAC6v3h7NEDro7V1n5mPMwwWhLcCOiW/Q0wQHUjUgM14gM\nEUhYVVpcbvaR3f25XwYhs/e3/ZL8Pw7sEPJWjztA5NUDg4Lq77y3xAx1tFKhvhr0\n9oKYYWRXOf/6TB7GwZhYv5GtqpytUHdujOqKQ/PGw9idBPKd2W5FGcwa309v0JTa\ndhiaUAxi19QJNwqxDHn665EBfAHqZE76h0TR2fXiQ8XfH0T7EQuTuSI4sAD1MYaS\nU/0YnEi9eulCVJNpD5CDVFjL1C5Oa/LkMTo/SubaAd7pTY9Uo3LOrykikRBozrMc\nisObanEZDyi+y435ZMfH4ikywJq7cN4Xnlis06nBcQKBgQDTv0JaX0ze8v6fiwaZ\nrbHvEehAyRvGGaY0/mxDYM9Ioq80aIAG5/Ogh3WGDyrynz4zCu1mqjRqterzpY+H\nSP6fZzhTi7lUHGVa4QUb4QlSkDWV0BED8we4AzXnBOHmto+aMwm1bi0O3qWcbWDk\nOacLIoAOhNKOn4IAzaHWAkgH6QKBgQC68LfXb9EEGafeHIjz2o08EhqHSoMs1kAp\nvu39vh3qdMIlSXWrmGXvQS4EJyBMyq24DLufUbEMRaf2yvbCpl0NRzo3dUeXXQWh\nLBT/9erKF10IjEHd8t4PUoE4JbtuLUPUAKBCx5pbtCcAMi1wWm+kcx9uLdKw/sPC\nKBKuRJTA4wKBgA4yYpaAkTzZeezke1rOZIGs56+ATFZp3dTrwgJ6eStbjPeskfjk\nkFcQ/fYxCiYeOyNc9jHN85m7/La9QPRHFptFZmdjlNdo1/rR32/RFLjuZklXG+zx\n3HCf9ns4vpSjZNln1pzNeEPo9Z2ZT8e9fc+nToKqsRtS4np/Tvx0RrQRAoGAB/Pd\nnkifd7Evtv83xEfz4i5S+pZs5idnK193+GdyFltJNxTc8KPXEkqPjpWrhhjJMx83\njBuJkKAV+SXBQZ6aLsps65cNqJ7IcobRjeIETvyXdJmi47JFSBmWbbENPC6oyAgO\nyUh8hJIxZoy76h+uyCwtlh5U7DqqUUQrJ0a7nUkCgYBoRunRKHNRycFlMFW2rLf+\n+ayC7fIPvLiKzYg2xAHIG/ykTGmtxrqKiVQ909FyVN7k9Rbyg9ZVZdkCqG/Br7iS\nVOF7xD1SCma3pdupRP4GIQSxVZVvUo48xzXNUFWXg4bjzMEgIErG12zL286blVPi\nxMz4TKijJq2YR67kdAEzDw==\n-----END PRIVATE KEY-----\n", + "client_email": "shandongchengda@chengda-467707.iam.gserviceaccount.com", + "client_id": "107299671168418329002", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/chengdatest%40chengda-466307.iam.gserviceaccount.com", + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/shandongchengda%40chengda-467707.iam.gserviceaccount.com", "universe_domain": "googleapis.com" } diff --git a/dl_admin/ruoyi-admin/src/main/resources/mapper/base/BaseSeoMapper.xml b/dl_admin/ruoyi-admin/src/main/resources/mapper/base/BaseSeoMapper.xml new file mode 100644 index 0000000..f0a613e --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/resources/mapper/base/BaseSeoMapper.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + select id, data_type, sort, title, content, description, pic, cn, creator, create_time, updater, update_time, del_flag from dl_base_seo + + + + \ No newline at end of file diff --git a/dl_admin/ruoyi-common/src/main/java/com/ruoyi/common/config/GoogleConfig.java b/dl_admin/ruoyi-common/src/main/java/com/ruoyi/common/config/GoogleConfig.java index cd88af1..4d4bed6 100644 --- a/dl_admin/ruoyi-common/src/main/java/com/ruoyi/common/config/GoogleConfig.java +++ b/dl_admin/ruoyi-common/src/main/java/com/ruoyi/common/config/GoogleConfig.java @@ -15,6 +15,7 @@ public class GoogleConfig { private Long customerId; private String developerToken; private String jsonPath; + private Long searchDown; } diff --git a/dl_vue/.env.development b/dl_vue/.env.development index 34d7a41..a050276 100644 --- a/dl_vue/.env.development +++ b/dl_vue/.env.development @@ -5,7 +5,7 @@ VUE_APP_TITLE = 成事达管理平台 ENV = 'development' # 成事达管理平台/开发环境 -VUE_APP_BASE_API = '/dev-api' +VUE_APP_BASE_API = 'http://127.0.0.1:8099' # 路由懒加载 VUE_CLI_BABEL_TRANSPILE_MODULES = true diff --git a/dl_vue/src/api/base/seo.js b/dl_vue/src/api/base/seo.js new file mode 100644 index 0000000..4d25782 --- /dev/null +++ b/dl_vue/src/api/base/seo.js @@ -0,0 +1,19 @@ +import request from '@/utils/request' + +// 查询SEO用到的国家和语言列表 +export function listSeo(query) { + return request({ + url: '/base/seo/list', + method: 'get', + params: query + }) +} + +// 查询关键词规划 +export function getKeywords(query) { + return request({ + url: '/base/seo/getKeywords', + method: 'get', + params: query + }) +} diff --git a/dl_vue/src/views/busi/prod/prodForm.vue b/dl_vue/src/views/busi/prod/prodForm.vue index 5b6b3b1..afb8053 100644 --- a/dl_vue/src/views/busi/prod/prodForm.vue +++ b/dl_vue/src/views/busi/prod/prodForm.vue @@ -6,99 +6,182 @@ 暂 存 发 布 相似度检测 + {{ showKeywords ? '关闭' : '打开' }}关键词推荐 - - - - -
- -
Google关键词获取
-
- -
-
- - -
- -
添加产品分类
-
-
-
- - - - - -
- - - - - - - - - - - - - - - - - - - - - 图片库选择 - - - - - - 图片库选择 - - - - - - - -
- - 插入换行符 -
-
-
- - + + + + + +
+ +
使用产品名称
+
+
+ + + + + + + + -
-
- - - -
+ + + + + + + + 搜索 + 重置 + + + 共抓取到{{keywordsList.length}}个关键词,月搜索量低于{{searchDown}}的关键词已为您自动忽略 + + + + + + + + + + + + + + + + + +
+ +
Google关键词获取
+
+ +
+
+ + +
+ +
添加产品分类
+
+
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + 图片库选择 + + + + + + 图片库选择 + + + + + + + +
+ + 插入换行符 +
+
+
+ + + + + + + +
+ + + +
+
+ @@ -115,7 +198,10 @@