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 5b010fa..80a032a 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 @@ -153,11 +153,11 @@ public class WebController extends BaseController { @ApiOperation("公司介绍-富文本-首页展示区域") @ApiImplicitParam(name = "tenantId", value = "站点唯一码", required = true, dataType = "string", paramType = "query", dataTypeClass = String.class) @GetMapping("/indexCompanyInfo") - public R> indexCompanyInfo(@RequestParam(required = true) String tenantId) { + public R> indexCompanyInfo(@RequestParam(required = true) String tenantId) { BaseSiteInfo baseSiteInfo = siteInfoService.getSiteInfo(tenantId); - Map map = new HashMap<>(); - map.put("content",baseSiteInfo.getCompanyInfo()); - map.put("contentApp",baseSiteInfo.getCompanyInfoApp()); + Map map = new HashMap<>(); + map.put("content", baseSiteInfo.getCompanyInfo()); + map.put("contentApp", baseSiteInfo.getCompanyInfoApp()); return R.ok(map); } @@ -233,10 +233,11 @@ public class WebController extends BaseController { @ApiImplicitParam(name = "tenantId", value = "站点唯一码", required = true, dataType = "string", paramType = "query", dataTypeClass = String.class), @ApiImplicitParam(name = "pageNum", value = "页码(1开始)", required = true, dataType = "int", paramType = "query", dataTypeClass = Integer.class), @ApiImplicitParam(name = "pageSize", value = "每页显示数量", required = true, dataType = "int", paramType = "query", dataTypeClass = Integer.class), - @ApiImplicitParam(name = "catgId", value = "分类id", required = false, dataType = "string", paramType = "query", dataTypeClass = String.class) + @ApiImplicitParam(name = "catgId", value = "分类id", required = false, dataType = "string", paramType = "query", dataTypeClass = String.class), + @ApiImplicitParam(name = "text", value = "搜索内容", required = false, dataType = "string", paramType = "query", dataTypeClass = String.class) }) @GetMapping("/prodPageList") - public R> prodPageList(String tenantId, String catgId, + public R> prodPageList(String tenantId, String catgId, String text, @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { Page page = new Page<>(pageNum, pageSize); @@ -244,6 +245,13 @@ public class WebController extends BaseController { .eq(BusiProdNew::getDataType, DATA_TYPE_PRODUCT) .eq(BusiProdNew::getIfPublic, true) .eq(BusiProdNew::getTenantId, tenantId); + if (StringUtils.isNotEmpty(text)) { + queryWrapper.and(wq -> wq + .like(BusiProdNew::getTitle, text) + .or().like(BusiProdNew::getDescription, text) + .or().like(BusiProdNew::getContent, text) + ); + } if (StringUtils.isNotEmpty(catgId)) { List catgIdList = new ArrayList<>(); catgIdList.add(catgId); @@ -257,9 +265,9 @@ public class WebController extends BaseController { category.setCatgType(CATG_TYPE_CP); List busiCategoryVOList = categoryService.treeCategory(category); //转map - Map catgMap = categoryService.dealFirstIdRtnMap(busiCategoryVOList); - IPage rtnPage = prodNewService.page(page,queryWrapper); - rtnPage.getRecords().forEach(item->item.setMaxCatgId(catgMap.getOrDefault(item.getCatgId(),""))); + Map catgMap = categoryService.dealFirstIdRtnMap(busiCategoryVOList); + IPage rtnPage = prodNewService.page(page, queryWrapper); + rtnPage.getRecords().forEach(item -> item.setMaxCatgId(catgMap.getOrDefault(item.getCatgId(), ""))); return R.ok(rtnPage); } @@ -279,10 +287,11 @@ public class WebController extends BaseController { @ApiImplicitParam(name = "tenantId", value = "站点唯一码", required = true, dataType = "string", paramType = "query", dataTypeClass = String.class), @ApiImplicitParam(name = "pageNum", value = "页码(1开始)", required = true, dataType = "int", paramType = "query", dataTypeClass = Integer.class), @ApiImplicitParam(name = "pageSize", value = "每页显示数量", required = true, dataType = "int", paramType = "query", dataTypeClass = Integer.class), - @ApiImplicitParam(name = "catgId", value = "分类id", required = false, dataType = "string", paramType = "query", dataTypeClass = String.class) + @ApiImplicitParam(name = "catgId", value = "分类id", required = false, dataType = "string", paramType = "query", dataTypeClass = String.class), + @ApiImplicitParam(name = "text", value = "搜索内容", required = false, dataType = "string", paramType = "query", dataTypeClass = String.class) }) @GetMapping("/newsPageList") - public R> newsPageList(String tenantId, String catgId, + public R> newsPageList(String tenantId, String catgId, String text, @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { Page page = new Page<>(pageNum, pageSize); @@ -290,6 +299,13 @@ public class WebController extends BaseController { .eq(BusiProdNew::getDataType, DATA_TYPE_NEWS) .eq(BusiProdNew::getIfPublic, true) .eq(BusiProdNew::getTenantId, tenantId); + if (StringUtils.isNotEmpty(text)) { + queryWrapper.and(wq -> wq + .like(BusiProdNew::getTitle, text) + .or().like(BusiProdNew::getDescription, text) + .or().like(BusiProdNew::getContent, text) + ); + } if (StringUtils.isNotEmpty(catgId)) { List catgIdList = new ArrayList<>(); catgIdList.add(catgId); @@ -303,9 +319,9 @@ public class WebController extends BaseController { category.setCatgType(CATG_TYPE_WZ); List busiCategoryVOList = categoryService.treeCategory(category); //转map - Map catgMap = categoryService.dealFirstIdRtnMap(busiCategoryVOList); + Map catgMap = categoryService.dealFirstIdRtnMap(busiCategoryVOList); IPage rtnPage = prodNewService.page(page, queryWrapper); - rtnPage.getRecords().forEach(item->item.setMaxCatgId(catgMap.getOrDefault(item.getCatgId(),""))); + rtnPage.getRecords().forEach(item -> item.setMaxCatgId(catgMap.getOrDefault(item.getCatgId(), ""))); return R.ok(rtnPage); } @@ -382,7 +398,7 @@ public class WebController extends BaseController { } return success(result); } else { - Map ipMap = commonUtils.getIPAndCountry(request); + Map ipMap = commonUtils.getIPAndCountry(request); busiChatMain.setIp(ipMap.get("ip")); busiChatMain.setNational(ipMap.get("national")); busiChatMain.setOceania(ipMap.get("oceania")); @@ -427,7 +443,7 @@ public class WebController extends BaseController { }) @PostMapping("/inquirySave") public R inquirySave(@ApiIgnore @RequestBody BusiInquiryItem inquiryItem, HttpServletRequest request) { - Map ipMap = commonUtils.getIPAndCountry(request); + Map ipMap = commonUtils.getIPAndCountry(request); inquiryItem.setIp(ipMap.get("ip")); inquiryItem.setNational(ipMap.get("national")); inquiryItem.setOceania(ipMap.get("oceania")); @@ -437,9 +453,10 @@ public class WebController extends BaseController { /** * 导航栏接口--所有分类 + * + * @return com.ruoyi.common.core.domain.AjaxResult * @author vinjor-M * @date 10:04 2025/7/8 - * @return com.ruoyi.common.core.domain.AjaxResult **/ @ApiOperation("站点地图使用接口") @ApiImplicitParams(value = { @@ -447,15 +464,16 @@ public class WebController extends BaseController { @ApiImplicitParam(name = "tenantId", value = "站点编码", required = true, dataType = "string", paramType = "query", dataTypeClass = String.class) }) @GetMapping("/siteMap") - public R> siteMap(@RequestParam(required = true) String tenantId, @RequestParam(required = true) String catgType){ - return R.ok(prodNewService.getSiteMap(tenantId,catgType)); + public R> siteMap(@RequestParam(required = true) String tenantId, @RequestParam(required = true) String catgType) { + return R.ok(prodNewService.getSiteMap(tenantId, catgType)); } /** * 记录网页访问次数 + * + * @return com.ruoyi.common.core.domain.AjaxResult * @author vinjor-M * @date 10:04 2025/7/8 - * @return com.ruoyi.common.core.domain.AjaxResult **/ @ApiOperation("记录网页访问次数") @ApiImplicitParams(value = { diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/controller/BusiKeywordItemController.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/controller/BusiKeywordItemController.java new file mode 100644 index 0000000..a15f029 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/controller/BusiKeywordItemController.java @@ -0,0 +1,126 @@ +package com.ruoyi.busi.controller; + +import java.util.*; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.busi.vo.BusiKeywordItemQueryVO; +import com.ruoyi.busi.vo.BusiKeywordRankStatVO; +import com.ruoyi.busi.vo.ChartDataVO; +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.busi.domain.BusiKeywordItem; +import com.ruoyi.busi.service.IBusiKeywordItemService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 关键词排名明细Controller + * + * @author vinjor-m + * @date 2025-08-21 + */ +@RestController +@RequestMapping("/busi/keywordItem") +public class BusiKeywordItemController extends BaseController +{ + @Autowired + private IBusiKeywordItemService busiKeywordItemService; + + /** + * 查询关键词排名明细列表 + */ + @PreAuthorize("@ss.hasPermi('busi:keywordItem:list')") + @GetMapping("/rankStat") + public AjaxResult inquiryCountryList(BusiKeywordItemQueryVO queryVO, + @RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize){ + Page page = new Page<>(pageNum, pageSize); + IPage result = busiKeywordItemService.selectKeywordRankStatPage(page, queryVO); + return success(result); + } + + /** + * 统计当天1-10名和11-20名的关键词数量 + */ + @GetMapping("/todayRankStat") + public AjaxResult todayRankStat(String tenantId) { + if (tenantId == null || tenantId.isEmpty()) { + return AjaxResult.error("租户ID不能为空"); + } + + Map result = busiKeywordItemService.selectTodayRankStat( tenantId); + return AjaxResult.success(result); + } + /** + * 导出关键词排名明细列表 + */ + @PreAuthorize("@ss.hasPermi('busi:keywordItem:export')") + @Log(title = "关键词排名明细", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, BusiKeywordItem busiKeywordItem) + { + List list = busiKeywordItemService.list(); + ExcelUtil util = new ExcelUtil(BusiKeywordItem.class); + util.exportExcel(response, list, "关键词排名明细数据"); + } + + /** + * 获取关键词排名明细详细信息 + */ + @PreAuthorize("@ss.hasPermi('busi:keywordItem:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return success(busiKeywordItemService.getById(id)); + } + + /** + * 新增关键词排名明细 + */ + @PreAuthorize("@ss.hasPermi('busi:keywordItem:add')") + @Log(title = "关键词排名明细", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody BusiKeywordItem busiKeywordItem) + { + return toAjax(busiKeywordItemService.save(busiKeywordItem)); + } + + /** + * 修改关键词排名明细 + */ + @PreAuthorize("@ss.hasPermi('busi:keywordItem:edit')") + @Log(title = "关键词排名明细", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody BusiKeywordItem busiKeywordItem) + { + return toAjax(busiKeywordItemService.updateById(busiKeywordItem)); + } + + /** + * 删除关键词排名明细 + */ + @PreAuthorize("@ss.hasPermi('busi:keywordItem:remove')") + @Log(title = "关键词排名明细", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) + { + List list = new ArrayList<>(Arrays.asList(ids)); + return toAjax(busiKeywordItemService.removeByIds(list)); + } +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/domain/BusiCategory.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/domain/BusiCategory.java index b48c161..0362542 100644 --- a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/domain/BusiCategory.java +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/domain/BusiCategory.java @@ -1,5 +1,6 @@ package com.ruoyi.busi.domain; +import com.baomidou.mybatisplus.annotation.TableField; import com.ruoyi.common.annotation.Excel; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; @@ -111,5 +112,4 @@ public class BusiCategory extends DlBaseEntity @Excel(name = "站点唯一编码", readConverterExp = "租=户id") @ApiModelProperty("站点唯一编码") private String tenantId; - } diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/domain/BusiKeyword.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/domain/BusiKeyword.java new file mode 100644 index 0000000..8e07e9d --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/domain/BusiKeyword.java @@ -0,0 +1,40 @@ +package com.ruoyi.busi.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import lombok.*; +import com.ruoyi.common.core.domain.DlBaseEntity; + +import java.util.Date; + +/** + * 站点使用的关键词对象 dl_busi_keyword + * + * @author vinjor-m + * @date 2025-08-21 + */ +@TableName("dl_busi_keyword") +@Data +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BusiKeyword +{ + private static final long serialVersionUID = 1L; + + /** 关键词 */ + @TableId + private String id; + + /** 站点唯一编码(租户id) */ + @Excel(name = "站点唯一编码", readConverterExp = "租户id") + private String tenantId; + + /** 创建时间 */ + @TableField(fill = FieldFill.INSERT) + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/domain/BusiKeywordItem.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/domain/BusiKeywordItem.java new file mode 100644 index 0000000..4abb11c --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/domain/BusiKeywordItem.java @@ -0,0 +1,49 @@ +package com.ruoyi.busi.domain; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +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; + +/** + * 关键词排名明细对象 dl_busi_keyword_item + * + * @author vinjor-m + * @date 2025-08-21 + */ +@TableName("dl_busi_keyword_item") +@Data +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BusiKeywordItem +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + @TableId(type = IdType.ASSIGN_UUID) + private String id; + + /** 关键词 */ + @Excel(name = "关键词") + private String title; + + /** 日期 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date selectDate; + + /** 排名 */ + @Excel(name = "排名") + private Integer ranking; + + /** 站点唯一编码(租户id) */ + @Excel(name = "站点唯一编码", readConverterExp = "租=户id") + private String tenantId; + +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/mapper/BusiKeywordItemMapper.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/mapper/BusiKeywordItemMapper.java new file mode 100644 index 0000000..080a2f1 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/mapper/BusiKeywordItemMapper.java @@ -0,0 +1,65 @@ +package com.ruoyi.busi.mapper; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.busi.domain.BusiKeywordItem; +import com.ruoyi.busi.vo.BusiKeywordRankStatVO; +import lombok.Data; +import org.apache.ibatis.annotations.Param; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 关键词排名明细Mapper接口 + * + * @author vinjor-m + * @date 2025-08-21 + */ +@Mapper +public interface BusiKeywordItemMapper extends BaseMapper +{ + IPage queryListPage(@Param("entity") BusiKeywordItem entity, Page page); + + int deleteBySelectDateInt(@Param("date") String date); + + /** + * 分页查询关键词基础信息 + */ + IPage selectKeywordPage( + IPage page, + @Param("title") String title, + @Param("tenantId") String tenantId + ); + + /** + * 查询关键词在时间范围内的排名数据 + */ + List selectRankDataByKeywordIds( + @Param("keywordIds") List keywordIds, + @Param("beginDate") Date beginDate, + @Param("endDate") Date endDate, + @Param("tenantId") String tenantId + ); + + @Data + class KeywordRankData { + private String keywordId; + private String selectDate; + private Integer ranking; + } + + /** + * 统计指定日期1-10名和11-20名的关键词数量 + * @param selectDate 选择日期 + * @param tenantId 租户ID + * @return 排名区间统计列表 + */ + List> selectTodayRankStat( + @Param("selectDate") Date selectDate, + @Param("tenantId") String tenantId + ); +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/mapper/BusiKeywordMapper.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/mapper/BusiKeywordMapper.java new file mode 100644 index 0000000..5c616e3 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/mapper/BusiKeywordMapper.java @@ -0,0 +1,29 @@ +package com.ruoyi.busi.mapper; + +import java.util.Date; +import java.util.List; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.busi.domain.BusiKeyword; +import org.apache.ibatis.annotations.Param; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 站点使用的关键词Mapper接口 + * + * @author vinjor-m + * @date 2025-08-21 + */ +@Mapper +public interface BusiKeywordMapper extends BaseMapper +{ + IPage queryListPage(@Param("entity") BusiKeyword entity, Page page); + /** + * 最新一次添加关键词的 时间 + * @author vinjor-M + * @date 14:32 2025/8/21 + **/ + Date selectNewDate(); + +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/mapper/BusiProdNewMapper.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/mapper/BusiProdNewMapper.java index 58f4d99..4c29ada 100644 --- a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/mapper/BusiProdNewMapper.java +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/mapper/BusiProdNewMapper.java @@ -1,5 +1,6 @@ package com.ruoyi.busi.mapper; +import java.util.Date; import java.util.List; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -45,4 +46,20 @@ public interface BusiProdNewMapper extends BaseMapper **/ BusiProdNew selectPreOrNext(@Param("dataType") String dataType,@Param("sort") Long sort,@Param("sortType") String sortType, @Param("tenantId") String tenantId,@Param("catgId") String catgId); + /** + * 查数据库中最新编辑的时间 + * @author vinjor-M + * @date 14:29 2025/8/21 + * @return java.util.Date + **/ + Date selectNewDate(); + + /** + * 查询更新时间晚于或等于某个时间的数据 + * @author vinjor-M + * @date 14:36 2025/8/21 + * @param updateTime 某个时间 + * @return java.util.List + **/ + List selectDataByUpdateTime(@Param("updateTime")String updateTime); } diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/IBusiKeywordItemService.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/IBusiKeywordItemService.java new file mode 100644 index 0000000..bab1d0c --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/IBusiKeywordItemService.java @@ -0,0 +1,46 @@ +package com.ruoyi.busi.service; + +import java.util.List; +import java.util.Map; + +import com.alibaba.fastjson2.JSONObject; +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.busi.domain.BusiKeywordItem; +import com.ruoyi.busi.vo.BusiKeywordItemQueryVO; +import com.ruoyi.busi.vo.BusiKeywordRankStatVO; + +/** + * 关键词排名明细Service接口 + * + * @author vinjor-m + * @date 2025-08-21 + */ +public interface IBusiKeywordItemService extends IService +{ + IPage queryListPage(BusiKeywordItem pageReqVO, Page page); + + /** + * 获取所有关键词的google排名 + * @author vinjor-M + * @date 15:10 2025/8/21 + **/ + void getKeywordRanking(); + + /** + * 分页查询关键词排名统计 + * @param page 分页参数 + * @param queryVO 查询参数 + * @return 分页结果 + */ + IPage selectKeywordRankStatPage(IPage page, BusiKeywordItemQueryVO queryVO); + + /** + * 统计当天1-10名和11-20名的关键词数量 + * @param selectDate 选择日期 + * @param tenantId 租户ID + * @return Map形式的统计结果 {key1: 1-10名数量, key2: 11-20名数量} + */ + Map selectTodayRankStat( String tenantId); +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/IBusiKeywordService.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/IBusiKeywordService.java new file mode 100644 index 0000000..af744d9 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/IBusiKeywordService.java @@ -0,0 +1,23 @@ +package com.ruoyi.busi.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.busi.domain.BusiKeyword; + +/** + * 站点使用的关键词Service接口 + * + * @author vinjor-m + * @date 2025-08-21 + */ +public interface IBusiKeywordService extends IService { + IPage queryListPage(BusiKeyword pageReqVO, Page page); + /** + * 检索全站使用的关键词 + * @author vinjor-M + * @date 14:26 2025/8/21 + **/ + void getAllKeyword(); +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/impl/BusiKeywordItemServiceImpl.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/impl/BusiKeywordItemServiceImpl.java new file mode 100644 index 0000000..1f77150 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/impl/BusiKeywordItemServiceImpl.java @@ -0,0 +1,153 @@ +package com.ruoyi.busi.service.impl; + +import java.util.*; +import java.util.stream.Collectors; + +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.busi.domain.BusiKeyword; +import com.ruoyi.busi.service.IBusiKeywordService; +import com.ruoyi.busi.vo.BusiKeywordItemQueryVO; +import com.ruoyi.busi.vo.BusiKeywordRankStatVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.busi.mapper.BusiKeywordItemMapper; +import com.ruoyi.busi.domain.BusiKeywordItem; +import com.ruoyi.busi.service.IBusiKeywordItemService; + +/** + * 关键词排名明细Service业务层处理 + * + * @author vinjor-m + * @date 2025-08-21 + */ +@Service +public class BusiKeywordItemServiceImpl extends ServiceImpl implements IBusiKeywordItemService +{ + @Autowired + private BusiKeywordItemMapper busiKeywordItemMapper; + @Autowired + private IBusiKeywordService busiKeywordService; + + @Override + public IPage queryListPage(BusiKeywordItem pageReqVO, Page page) { + return busiKeywordItemMapper.queryListPage(pageReqVO, page); + } + + /** + * 获取所有关键词的google排名 + * + * @author vinjor-M + * @date 15:10 2025/8/21 + **/ + @Override + public void getKeywordRanking() { + Date nowDate = new Date(); + List keywordList = busiKeywordService.list(); + //删除今日所有的排名数据 + busiKeywordItemMapper.deleteBySelectDateInt(DateUtil.formatDate(nowDate)); + List insertList = new ArrayList<>(); + for (BusiKeyword keyword : keywordList) { + BusiKeywordItem busiKeywordItem = new BusiKeywordItem(); + busiKeywordItem.setTitle(keyword.getId()); + busiKeywordItem.setSelectDate(nowDate); + //TODO 调朱哥的接口获取排名 + busiKeywordItem.setRanking(1); + busiKeywordItem.setTenantId(keyword.getTenantId()); + insertList.add(busiKeywordItem); + } + if(!insertList.isEmpty()){ + this.saveBatch(insertList); + } + } + + @Override + public IPage selectKeywordRankStatPage(IPage page, BusiKeywordItemQueryVO queryVO) { + // 查询关键词数据 + IPage resultPage = busiKeywordItemMapper.selectKeywordPage( + page, + queryVO.getTitle(), + queryVO.getTenantId() + ); + + // 生成查询日期范围内的所有日期列表 + List dateList = generateDateList(queryVO.getBeginDate(), queryVO.getEndDate()); + + // 查询每个关键词的详细排名数据 + if (resultPage.getRecords() != null && !resultPage.getRecords().isEmpty()) { + List keywordIds = resultPage.getRecords().stream() + .map(BusiKeywordRankStatVO::getId) + .collect(Collectors.toList()); + + List rankDataList = busiKeywordItemMapper.selectRankDataByKeywordIds( + keywordIds, + queryVO.getBeginDate(), + queryVO.getEndDate(), + queryVO.getTenantId() + ); + + // 按关键词ID分组排名数据 + Map> keywordRankMap = + rankDataList.stream().collect(Collectors.groupingBy(BusiKeywordItemMapper.KeywordRankData::getKeywordId)); + + // 为每个关键词构建每日排名映射 + resultPage.getRecords().forEach(record -> { + Map dailyRankings = new LinkedHashMap<>(); + + // 初始化查询日期范围内的每一天,排名设为null + dateList.forEach(date -> dailyRankings.put(date, null)); + + // 填充实际有数据的排名 + List dataList = keywordRankMap.getOrDefault(record.getId(), new ArrayList<>()); + dataList.forEach(data -> dailyRankings.put(data.getSelectDate(), data.getRanking())); + + record.setDailyRankings(dailyRankings); + }); + } + return resultPage; + } + + + /** + * 生成日期范围内的所有日期列表 + * @param beginDate 开始日期 + * @param endDate 结束日期 + * @return 日期字符串列表 (yyyy-MM-dd格式) + */ + private List generateDateList(Date beginDate, Date endDate) { + List dateList = new ArrayList<>(); + if (beginDate == null || endDate == null) { + return dateList; + } + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(beginDate); + + while (!calendar.getTime().after(endDate)) { + dateList.add(DateUtil.format(calendar.getTime(), "yyyy-MM-dd")); + calendar.add(Calendar.DAY_OF_MONTH, 1); + } + + return dateList; + } + + @Override + public Map selectTodayRankStat(String tenantId) { + List> resultList = busiKeywordItemMapper.selectTodayRankStat(new Date(), tenantId); + + Map resultMap = new HashMap<>(); + resultMap.put("key1", 0); // 1-10名默认为0 + resultMap.put("key2", 0); // 11-20名默认为0 + + for (Map row : resultList) { + String rangeKey = (String) row.get("rangeKey"); + Integer count = ((Long) row.get("count")).intValue(); + resultMap.put(rangeKey, count); + } + + return resultMap; + } +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/impl/BusiKeywordServiceImpl.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/impl/BusiKeywordServiceImpl.java new file mode 100644 index 0000000..d6c86e7 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/impl/BusiKeywordServiceImpl.java @@ -0,0 +1,80 @@ +package com.ruoyi.busi.service.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.busi.domain.BusiProdNew; +import com.ruoyi.busi.mapper.BusiProdNewMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.busi.mapper.BusiKeywordMapper; +import com.ruoyi.busi.domain.BusiKeyword; +import com.ruoyi.busi.service.IBusiKeywordService; + +/** + * 站点使用的关键词Service业务层处理 + * + * @author vinjor-m + * @date 2025-08-21 + */ +@Service +public class BusiKeywordServiceImpl extends ServiceImpl implements IBusiKeywordService +{ + @Autowired + private BusiKeywordMapper busiKeywordMapper; + @Autowired + private BusiProdNewMapper busiProdNewMapper; + + @Override + public IPage queryListPage(BusiKeyword pageReqVO, Page page) { + return busiKeywordMapper.queryListPage(pageReqVO, page); + } + + /** + * 检索全站使用的关键词 + * + * @author vinjor-M + * @date 14:26 2025/8/21 + **/ + @Override + public void getAllKeyword() { + //最近一次编辑产品或文章的时间 + Date newDate = busiProdNewMapper.selectNewDate(); + if(null==newDate){ + //没有新增或编辑文章,不需要采集 + return; + } + //最近一次插入关键词的时间 + Date insertDate = busiKeywordMapper.selectNewDate(); + if (null==insertDate || newDate.after(insertDate)) { + //当前时间 + Date nowDate = new Date(); + //编辑文章的时间晚于最近关键词插入的时间,需要采集关键词 + List dataList = busiProdNewMapper.selectDataByUpdateTime(null==insertDate?null:insertDate.toString()); + if(!dataList.isEmpty()){ + //使用的关键词不为空 + List insertList = new ArrayList<>(); + for (BusiProdNew prodNew : dataList){ + List thisKeywordList = Arrays.asList(prodNew.getProdKeyword().split(StrUtil.COMMA)); + thisKeywordList.forEach(item -> { + BusiKeyword keywordItem = new BusiKeyword(); + keywordItem.setId(item); + keywordItem.setTenantId(prodNew.getTenantId()); + keywordItem.setCreateTime(nowDate); + insertList.add(keywordItem); + }); + } + if(!insertList.isEmpty()){ + this.saveOrUpdateBatch(insertList); + } + } + } + } +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/vo/BusiKeywordItemQueryVO.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/vo/BusiKeywordItemQueryVO.java new file mode 100644 index 0000000..b55ea24 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/vo/BusiKeywordItemQueryVO.java @@ -0,0 +1,26 @@ +package com.ruoyi.busi.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.util.Date; + +/** + * 关键词排名查询参数VO + */ +@Data +public class BusiKeywordItemQueryVO { + /** 关键词模糊查询 */ + private String title; + + /** 查询开始时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + private Date beginDate; + + /** 查询结束时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + private Date endDate; + + /** 租户ID */ + private String tenantId; +} diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/vo/BusiKeywordRankStatVO.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/vo/BusiKeywordRankStatVO.java new file mode 100644 index 0000000..ef75d0d --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/vo/BusiKeywordRankStatVO.java @@ -0,0 +1,24 @@ + +package com.ruoyi.busi.vo; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +/** + * 关键词排名统计结果VO + */ +@Data +public class BusiKeywordRankStatVO { + /** 关键词ID */ + private String id; + + /** 关键词标题 */ + private String title; + + /** 每日排名数据 Map<日期, 排名> */ + private Map dailyRankings; +} \ No newline at end of file diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/task/BusiTask.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/task/BusiTask.java new file mode 100644 index 0000000..260a51c --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/task/BusiTask.java @@ -0,0 +1,39 @@ +package com.ruoyi.task; + +import cn.hutool.core.date.DateUtil; +import com.ruoyi.busi.service.IBusiKeywordItemService; +import com.ruoyi.busi.service.IBusiKeywordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 业务模块定时任务调度 + * + * @author vinjor-m + */ +@Component("busiTask") +public class BusiTask { + @Autowired + private IBusiKeywordService busiKeywordService; + @Autowired + private IBusiKeywordItemService busiKeywordItemService; + /** + * 更新本站使用的关键词 + * @author vinjor-M + * @date 14:51 2025/8/21 + **/ + public void updateKeyword() { + busiKeywordService.getAllKeyword(); + System.out.println("【"+ DateUtil.now() +"】执行更新本站使用关键词成功"); + } + + /** + * 更新本站使用的关键词的google排名 + * @author vinjor-M + * @date 14:51 2025/8/21 + **/ + public void updateKeywordRanking() { + busiKeywordItemService.getKeywordRanking(); + System.out.println("【"+ DateUtil.now() +"】执行更新本站使用关键词google排名成功"); + } +} diff --git a/dl_admin/ruoyi-admin/src/main/resources/application-druid.yml b/dl_admin/ruoyi-admin/src/main/resources/application-druid.yml index ca19f11..4e6a73d 100644 --- a/dl_admin/ruoyi-admin/src/main/resources/application-druid.yml +++ b/dl_admin/ruoyi-admin/src/main/resources/application-druid.yml @@ -5,15 +5,15 @@ spring: driverClassName: com.mysql.cj.jdbc.Driver druid: # 主库数据源-点亮开发库 -# master: -# url: jdbc:mysql://82.156.161.160:3306/dl_site_system?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 -# username: site -# password: 123456 - # 主库数据源-客户测试服务器 master: - url: jdbc:mysql://114.132.197.85:3306/dl_site_system?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + url: jdbc:mysql://82.156.161.160:3306/dl_site_system?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: site password: 123456 + #主库数据源-客户测试服务器 +# master: +# url: jdbc:mysql://114.132.197.85:3306/dl_site_system?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 +# username: site +# password: 123456 # 从库数据源 slave: # 从数据源开关/默认关闭 diff --git a/dl_admin/ruoyi-admin/src/main/resources/mapper/busi/BusiKeywordItemMapper.xml b/dl_admin/ruoyi-admin/src/main/resources/mapper/busi/BusiKeywordItemMapper.xml new file mode 100644 index 0000000..ee5d6b9 --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/resources/mapper/busi/BusiKeywordItemMapper.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + select id, title, select_date, ranking, tenant_id from dl_busi_keyword_item + + + delete from dl_busi_keyword_item where select_date = #{date} + + + + + + + + + \ No newline at end of file diff --git a/dl_admin/ruoyi-admin/src/main/resources/mapper/busi/BusiKeywordMapper.xml b/dl_admin/ruoyi-admin/src/main/resources/mapper/busi/BusiKeywordMapper.xml new file mode 100644 index 0000000..9716e1b --- /dev/null +++ b/dl_admin/ruoyi-admin/src/main/resources/mapper/busi/BusiKeywordMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + select id, tenant_id from dl_busi_keyword + + + + + \ No newline at end of file diff --git a/dl_admin/ruoyi-admin/src/main/resources/mapper/busi/BusiProdNewMapper.xml b/dl_admin/ruoyi-admin/src/main/resources/mapper/busi/BusiProdNewMapper.xml index cc249fe..dfb626b 100644 --- a/dl_admin/ruoyi-admin/src/main/resources/mapper/busi/BusiProdNewMapper.xml +++ b/dl_admin/ruoyi-admin/src/main/resources/mapper/busi/BusiProdNewMapper.xml @@ -179,4 +179,21 @@ + + \ No newline at end of file diff --git a/dl_vue/src/api/busi/keywordItem.js b/dl_vue/src/api/busi/keywordItem.js new file mode 100644 index 0000000..37bcabd --- /dev/null +++ b/dl_vue/src/api/busi/keywordItem.js @@ -0,0 +1,52 @@ +import request from '@/utils/request' + +// 查询关键词排名明细列表 +export function listKeywordItem(query) { + return request({ + url: '/busi/keywordItem/rankStat', + method: 'get', + params: query + }) +} +// 查询关键词排名明细列表 +export function todayRankStat(query) { + return request({ + url: '/busi/keywordItem/todayRankStat', + method: 'get', + params: query + }) +} + +// 查询关键词排名明细详细 +export function getKeywordItem(id) { + return request({ + url: '/busi/keywordItem/' + id, + method: 'get' + }) +} + +// 新增关键词排名明细 +export function addKeywordItem(data) { + return request({ + url: '/busi/keywordItem', + method: 'post', + data: data + }) +} + +// 修改关键词排名明细 +export function updateKeywordItem(data) { + return request({ + url: '/busi/keywordItem', + method: 'put', + data: data + }) +} + +// 删除关键词排名明细 +export function delKeywordItem(id) { + return request({ + url: '/busi/keywordItem/' + id, + method: 'delete' + }) +} diff --git a/dl_vue/src/views/busi/category/form/categoryForm.vue b/dl_vue/src/views/busi/category/form/categoryForm.vue index c99a273..5314fb6 100644 --- a/dl_vue/src/views/busi/category/form/categoryForm.vue +++ b/dl_vue/src/views/busi/category/form/categoryForm.vue @@ -101,6 +101,14 @@ + @@ -113,6 +121,14 @@ + diff --git a/dl_vue/src/views/busi/keywordItem/index.vue b/dl_vue/src/views/busi/keywordItem/index.vue new file mode 100644 index 0000000..71af85c --- /dev/null +++ b/dl_vue/src/views/busi/keywordItem/index.vue @@ -0,0 +1,242 @@ + + + + + diff --git a/dl_vue/src/views/busi/new/newForm.vue b/dl_vue/src/views/busi/new/newForm.vue index ff7c240..f6fd7ed 100644 --- a/dl_vue/src/views/busi/new/newForm.vue +++ b/dl_vue/src/views/busi/new/newForm.vue @@ -112,6 +112,14 @@ + @@ -124,6 +132,14 @@ + diff --git a/dl_vue/src/views/busi/prod/prodForm.vue b/dl_vue/src/views/busi/prod/prodForm.vue index 900251c..be95317 100644 --- a/dl_vue/src/views/busi/prod/prodForm.vue +++ b/dl_vue/src/views/busi/prod/prodForm.vue @@ -109,6 +109,14 @@ + @@ -121,6 +129,14 @@ +