关键词排名
This commit is contained in:
parent
5b1074a8db
commit
0ec0e03967
@ -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<Map<String,String>> indexCompanyInfo(@RequestParam(required = true) String tenantId) {
|
||||
public R<Map<String, String>> indexCompanyInfo(@RequestParam(required = true) String tenantId) {
|
||||
BaseSiteInfo baseSiteInfo = siteInfoService.getSiteInfo(tenantId);
|
||||
Map<String,String> map = new HashMap<>();
|
||||
map.put("content",baseSiteInfo.getCompanyInfo());
|
||||
map.put("contentApp",baseSiteInfo.getCompanyInfoApp());
|
||||
Map<String, String> 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<IPage<BusiProdNew>> prodPageList(String tenantId, String catgId,
|
||||
public R<IPage<BusiProdNew>> prodPageList(String tenantId, String catgId, String text,
|
||||
@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
Page<BusiProdNew> 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<String> catgIdList = new ArrayList<>();
|
||||
catgIdList.add(catgId);
|
||||
@ -257,9 +265,9 @@ public class WebController extends BaseController {
|
||||
category.setCatgType(CATG_TYPE_CP);
|
||||
List<BusiCategoryVO> busiCategoryVOList = categoryService.treeCategory(category);
|
||||
//转map
|
||||
Map<String,String> catgMap = categoryService.dealFirstIdRtnMap(busiCategoryVOList);
|
||||
IPage<BusiProdNew> rtnPage = prodNewService.page(page,queryWrapper);
|
||||
rtnPage.getRecords().forEach(item->item.setMaxCatgId(catgMap.getOrDefault(item.getCatgId(),"")));
|
||||
Map<String, String> catgMap = categoryService.dealFirstIdRtnMap(busiCategoryVOList);
|
||||
IPage<BusiProdNew> 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<IPage<BusiProdNew>> newsPageList(String tenantId, String catgId,
|
||||
public R<IPage<BusiProdNew>> newsPageList(String tenantId, String catgId, String text,
|
||||
@RequestParam(name = "pageNum", defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
Page<BusiProdNew> 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<String> catgIdList = new ArrayList<>();
|
||||
catgIdList.add(catgId);
|
||||
@ -303,9 +319,9 @@ public class WebController extends BaseController {
|
||||
category.setCatgType(CATG_TYPE_WZ);
|
||||
List<BusiCategoryVO> busiCategoryVOList = categoryService.treeCategory(category);
|
||||
//转map
|
||||
Map<String,String> catgMap = categoryService.dealFirstIdRtnMap(busiCategoryVOList);
|
||||
Map<String, String> catgMap = categoryService.dealFirstIdRtnMap(busiCategoryVOList);
|
||||
IPage<BusiProdNew> 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<String,String> ipMap = commonUtils.getIPAndCountry(request);
|
||||
Map<String, String> 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<String> inquirySave(@ApiIgnore @RequestBody BusiInquiryItem inquiryItem, HttpServletRequest request) {
|
||||
Map<String,String> ipMap = commonUtils.getIPAndCountry(request);
|
||||
Map<String, String> 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<List<SiteMapVO>> siteMap(@RequestParam(required = true) String tenantId, @RequestParam(required = true) String catgType){
|
||||
return R.ok(prodNewService.getSiteMap(tenantId,catgType));
|
||||
public R<List<SiteMapVO>> 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 = {
|
||||
|
||||
@ -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<BusiKeywordRankStatVO> page = new Page<>(pageNum, pageSize);
|
||||
IPage<BusiKeywordRankStatVO> 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<String, Integer> 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<BusiKeywordItem> list = busiKeywordItemService.list();
|
||||
ExcelUtil<BusiKeywordItem> util = new ExcelUtil<BusiKeywordItem>(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<String> list = new ArrayList<>(Arrays.asList(ids));
|
||||
return toAjax(busiKeywordItemService.removeByIds(list));
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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<BusiKeywordItem>
|
||||
{
|
||||
IPage<BusiKeywordItem> queryListPage(@Param("entity") BusiKeywordItem entity, Page<BusiKeywordItem> page);
|
||||
|
||||
int deleteBySelectDateInt(@Param("date") String date);
|
||||
|
||||
/**
|
||||
* 分页查询关键词基础信息
|
||||
*/
|
||||
IPage<BusiKeywordRankStatVO> selectKeywordPage(
|
||||
IPage<BusiKeywordRankStatVO> page,
|
||||
@Param("title") String title,
|
||||
@Param("tenantId") String tenantId
|
||||
);
|
||||
|
||||
/**
|
||||
* 查询关键词在时间范围内的排名数据
|
||||
*/
|
||||
List<KeywordRankData> selectRankDataByKeywordIds(
|
||||
@Param("keywordIds") List<String> 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<Map<String, Object>> selectTodayRankStat(
|
||||
@Param("selectDate") Date selectDate,
|
||||
@Param("tenantId") String tenantId
|
||||
);
|
||||
}
|
||||
@ -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<BusiKeyword>
|
||||
{
|
||||
IPage<BusiKeyword> queryListPage(@Param("entity") BusiKeyword entity, Page<BusiKeyword> page);
|
||||
/**
|
||||
* 最新一次添加关键词的 时间
|
||||
* @author vinjor-M
|
||||
* @date 14:32 2025/8/21
|
||||
**/
|
||||
Date selectNewDate();
|
||||
|
||||
}
|
||||
@ -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>
|
||||
**/
|
||||
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<com.ruoyi.busi.domain.BusiProdNew>
|
||||
**/
|
||||
List<BusiProdNew> selectDataByUpdateTime(@Param("updateTime")String updateTime);
|
||||
}
|
||||
|
||||
@ -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<BusiKeywordItem>
|
||||
{
|
||||
IPage<BusiKeywordItem> queryListPage(BusiKeywordItem pageReqVO, Page<BusiKeywordItem> page);
|
||||
|
||||
/**
|
||||
* 获取所有关键词的google排名
|
||||
* @author vinjor-M
|
||||
* @date 15:10 2025/8/21
|
||||
**/
|
||||
void getKeywordRanking();
|
||||
|
||||
/**
|
||||
* 分页查询关键词排名统计
|
||||
* @param page 分页参数
|
||||
* @param queryVO 查询参数
|
||||
* @return 分页结果
|
||||
*/
|
||||
IPage<BusiKeywordRankStatVO> selectKeywordRankStatPage(IPage<BusiKeywordRankStatVO> page, BusiKeywordItemQueryVO queryVO);
|
||||
|
||||
/**
|
||||
* 统计当天1-10名和11-20名的关键词数量
|
||||
* @param selectDate 选择日期
|
||||
* @param tenantId 租户ID
|
||||
* @return Map形式的统计结果 {key1: 1-10名数量, key2: 11-20名数量}
|
||||
*/
|
||||
Map<String, Integer> selectTodayRankStat( String tenantId);
|
||||
}
|
||||
@ -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<BusiKeyword> {
|
||||
IPage<BusiKeyword> queryListPage(BusiKeyword pageReqVO, Page<BusiKeyword> page);
|
||||
/**
|
||||
* 检索全站使用的关键词
|
||||
* @author vinjor-M
|
||||
* @date 14:26 2025/8/21
|
||||
**/
|
||||
void getAllKeyword();
|
||||
}
|
||||
@ -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<BusiKeywordItemMapper,BusiKeywordItem> implements IBusiKeywordItemService
|
||||
{
|
||||
@Autowired
|
||||
private BusiKeywordItemMapper busiKeywordItemMapper;
|
||||
@Autowired
|
||||
private IBusiKeywordService busiKeywordService;
|
||||
|
||||
@Override
|
||||
public IPage<BusiKeywordItem> queryListPage(BusiKeywordItem pageReqVO, Page<BusiKeywordItem> 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<BusiKeyword> keywordList = busiKeywordService.list();
|
||||
//删除今日所有的排名数据
|
||||
busiKeywordItemMapper.deleteBySelectDateInt(DateUtil.formatDate(nowDate));
|
||||
List<BusiKeywordItem> 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<BusiKeywordRankStatVO> selectKeywordRankStatPage(IPage<BusiKeywordRankStatVO> page, BusiKeywordItemQueryVO queryVO) {
|
||||
// 查询关键词数据
|
||||
IPage<BusiKeywordRankStatVO> resultPage = busiKeywordItemMapper.selectKeywordPage(
|
||||
page,
|
||||
queryVO.getTitle(),
|
||||
queryVO.getTenantId()
|
||||
);
|
||||
|
||||
// 生成查询日期范围内的所有日期列表
|
||||
List<String> dateList = generateDateList(queryVO.getBeginDate(), queryVO.getEndDate());
|
||||
|
||||
// 查询每个关键词的详细排名数据
|
||||
if (resultPage.getRecords() != null && !resultPage.getRecords().isEmpty()) {
|
||||
List<String> keywordIds = resultPage.getRecords().stream()
|
||||
.map(BusiKeywordRankStatVO::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<BusiKeywordItemMapper.KeywordRankData> rankDataList = busiKeywordItemMapper.selectRankDataByKeywordIds(
|
||||
keywordIds,
|
||||
queryVO.getBeginDate(),
|
||||
queryVO.getEndDate(),
|
||||
queryVO.getTenantId()
|
||||
);
|
||||
|
||||
// 按关键词ID分组排名数据
|
||||
Map<String, List<BusiKeywordItemMapper.KeywordRankData>> keywordRankMap =
|
||||
rankDataList.stream().collect(Collectors.groupingBy(BusiKeywordItemMapper.KeywordRankData::getKeywordId));
|
||||
|
||||
// 为每个关键词构建每日排名映射
|
||||
resultPage.getRecords().forEach(record -> {
|
||||
Map<String, Integer> dailyRankings = new LinkedHashMap<>();
|
||||
|
||||
// 初始化查询日期范围内的每一天,排名设为null
|
||||
dateList.forEach(date -> dailyRankings.put(date, null));
|
||||
|
||||
// 填充实际有数据的排名
|
||||
List<BusiKeywordItemMapper.KeywordRankData> 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<String> generateDateList(Date beginDate, Date endDate) {
|
||||
List<String> 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<String, Integer> selectTodayRankStat(String tenantId) {
|
||||
List<Map<String, Object>> resultList = busiKeywordItemMapper.selectTodayRankStat(new Date(), tenantId);
|
||||
|
||||
Map<String, Integer> resultMap = new HashMap<>();
|
||||
resultMap.put("key1", 0); // 1-10名默认为0
|
||||
resultMap.put("key2", 0); // 11-20名默认为0
|
||||
|
||||
for (Map<String, Object> row : resultList) {
|
||||
String rangeKey = (String) row.get("rangeKey");
|
||||
Integer count = ((Long) row.get("count")).intValue();
|
||||
resultMap.put(rangeKey, count);
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
}
|
||||
@ -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<BusiKeywordMapper,BusiKeyword> implements IBusiKeywordService
|
||||
{
|
||||
@Autowired
|
||||
private BusiKeywordMapper busiKeywordMapper;
|
||||
@Autowired
|
||||
private BusiProdNewMapper busiProdNewMapper;
|
||||
|
||||
@Override
|
||||
public IPage<BusiKeyword> queryListPage(BusiKeyword pageReqVO, Page<BusiKeyword> 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<BusiProdNew> dataList = busiProdNewMapper.selectDataByUpdateTime(null==insertDate?null:insertDate.toString());
|
||||
if(!dataList.isEmpty()){
|
||||
//使用的关键词不为空
|
||||
List<BusiKeyword> insertList = new ArrayList<>();
|
||||
for (BusiProdNew prodNew : dataList){
|
||||
List<String> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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<String, Integer> dailyRankings;
|
||||
}
|
||||
@ -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排名成功");
|
||||
}
|
||||
}
|
||||
@ -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:
|
||||
# 从数据源开关/默认关闭
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.busi.mapper.BusiKeywordItemMapper">
|
||||
|
||||
<resultMap type="BusiKeywordItem" id="BusiKeywordItemResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="title" column="title" />
|
||||
<result property="selectDate" column="select_date" />
|
||||
<result property="ranking" column="ranking" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectBusiKeywordItemVo">
|
||||
select id, title, select_date, ranking, tenant_id from dl_busi_keyword_item
|
||||
</sql>
|
||||
<delete id="deleteBySelectDateInt">
|
||||
delete from dl_busi_keyword_item where select_date = #{date}
|
||||
</delete>
|
||||
|
||||
<select id="queryListPage" parameterType="BusiKeywordItem" resultMap="BusiKeywordItemResult">
|
||||
<include refid="selectBusiKeywordItemVo"/>
|
||||
<where>
|
||||
<if test="entity.title != null and entity.title != ''"> and title = #{entity.title}</if>
|
||||
<if test="entity.selectDate != null "> and select_date = #{entity.selectDate}</if>
|
||||
<if test="entity.ranking != null "> and ranking = #{entity.ranking}</if>
|
||||
<if test="entity.tenantId != null and entity.tenantId != ''"> and tenant_id = #{entity.tenantId}</if>
|
||||
</where>
|
||||
</select>
|
||||
<select id="selectKeywordPage" resultType="com.ruoyi.busi.vo.BusiKeywordRankStatVO">
|
||||
SELECT
|
||||
k.id,
|
||||
k.id AS title
|
||||
FROM dl_busi_keyword k
|
||||
<where>
|
||||
1=1
|
||||
<if test="tenantId != null and tenantId != ''">
|
||||
AND k.tenant_id = #{tenantId}
|
||||
</if>
|
||||
<if test="title != null and title != ''">
|
||||
AND k.id LIKE CONCAT('%', #{title}, '%')
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY k.create_time DESC
|
||||
</select>
|
||||
|
||||
<select id="selectRankDataByKeywordIds" resultType="com.ruoyi.busi.mapper.BusiKeywordItemMapper$KeywordRankData">
|
||||
SELECT
|
||||
ki.title as keywordId,
|
||||
DATE_FORMAT(ki.select_date, '%Y-%m-%d') as selectDate,
|
||||
ki.ranking
|
||||
FROM dl_busi_keyword_item ki
|
||||
WHERE ki.tenant_id = #{tenantId}
|
||||
AND ki.title IN
|
||||
<foreach collection="keywordIds" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
<if test="beginDate != null">
|
||||
AND ki.select_date >= #{beginDate}
|
||||
</if>
|
||||
<if test="endDate != null">
|
||||
AND ki.select_date <= #{endDate}
|
||||
</if>
|
||||
ORDER BY ki.select_date ASC
|
||||
</select>
|
||||
<select id="selectTodayRankStat" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
CASE
|
||||
WHEN ranking BETWEEN 1 AND 10 THEN 'key1'
|
||||
WHEN ranking BETWEEN 11 AND 20 THEN 'key2'
|
||||
END as rangeKey,
|
||||
COUNT(*) as count
|
||||
FROM dl_busi_keyword_item
|
||||
WHERE tenant_id = #{tenantId}
|
||||
AND DATE_FORMAT(select_date, '%Y-%m-%d') = DATE_FORMAT(#{selectDate}, '%Y-%m-%d')
|
||||
AND ranking BETWEEN 1 AND 20
|
||||
GROUP BY
|
||||
CASE
|
||||
WHEN ranking BETWEEN 1 AND 10 THEN 'key1'
|
||||
WHEN ranking BETWEEN 11 AND 20 THEN 'key2'
|
||||
END
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN ranking BETWEEN 1 AND 10 THEN 1
|
||||
WHEN ranking BETWEEN 11 AND 20 THEN 2
|
||||
END
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.busi.mapper.BusiKeywordMapper">
|
||||
|
||||
<resultMap type="BusiKeyword" id="BusiKeywordResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="tenantId" column="tenant_id" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectBusiKeywordVo">
|
||||
select id, tenant_id from dl_busi_keyword
|
||||
</sql>
|
||||
|
||||
<select id="queryListPage" parameterType="BusiKeyword" resultMap="BusiKeywordResult">
|
||||
<include refid="selectBusiKeywordVo"/>
|
||||
<where>
|
||||
<if test="entity.tenantId != null and entity.tenantId != ''"> and tenant_id = #{entity.tenantId}</if>
|
||||
</where>
|
||||
</select>
|
||||
<select id="selectNewDate" resultType="java.util.Date">
|
||||
select max(create_time) from dl_busi_keyword
|
||||
</select>
|
||||
</mapper>
|
||||
@ -179,4 +179,21 @@
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<select id="selectNewDate" resultType="java.util.Date">
|
||||
SELECT
|
||||
MAX( create_time )
|
||||
FROM
|
||||
dl_busi_prod_new
|
||||
WHERE
|
||||
del_flag = '0'
|
||||
</select>
|
||||
<select id="selectDataByUpdateTime" resultType="com.ruoyi.busi.domain.BusiProdNew">
|
||||
SELECT *
|
||||
FROM dl_busi_prod_new
|
||||
WHERE del_flag = '0'
|
||||
AND prod_keyword is not null and prod_keyword!=''
|
||||
<if test="updateTime != null and updateTime != ''">
|
||||
AND update_time >= #{updateTime}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
52
dl_vue/src/api/busi/keywordItem.js
Normal file
52
dl_vue/src/api/busi/keywordItem.js
Normal file
@ -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'
|
||||
})
|
||||
}
|
||||
@ -101,6 +101,14 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<template v-slot:label>
|
||||
<span>排序</span>
|
||||
<el-tooltip class="item" effect="dark" content="数字越大越靠前"
|
||||
placement="bottom"
|
||||
>
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="form.sort" type="number" placeholder="请输入排序"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -113,6 +121,14 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="页面keyword" prop="keyword">
|
||||
<template v-slot:label>
|
||||
<span>页面keyword</span>
|
||||
<el-tooltip class="item" effect="dark" content="请确保多个关键词用英文逗号','隔开"
|
||||
placement="bottom"
|
||||
>
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input type="textarea" v-model="form.keyword" placeholder="请输入页面keyword"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
242
dl_vue/src/views/busi/keywordItem/index.vue
Normal file
242
dl_vue/src/views/busi/keywordItem/index.vue
Normal file
@ -0,0 +1,242 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 今日报表情况展示 -->
|
||||
<div v-if="todayRankData" class="today-rank-summary">
|
||||
今日报表情况:1-10位<span>{{ todayRankData.key1 }}</span>个词,11-20位<span>{{ todayRankData.key2 }}</span>个词
|
||||
</div>
|
||||
<!-- 查询条件 -->
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="关键词" prop="title">
|
||||
<el-input
|
||||
v-model="queryParams.title"
|
||||
placeholder="请输入关键词"
|
||||
clearable
|
||||
size="small"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="日期范围">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
size="small" style="width: 240px"
|
||||
value-format="yyyy-MM-dd"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-table v-loading="loading" :data="keywordList" :default-sort="{prop: 'id', order: 'descending'}">
|
||||
<el-table-column label="关键词" align="center" prop="title" fixed width="200" />
|
||||
|
||||
<!-- 动态生成日期列 -->
|
||||
<el-table-column
|
||||
v-for="date in dateList"
|
||||
:key="date"
|
||||
:label="formatDateLabel(date)"
|
||||
align="center"
|
||||
min-width="80"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span :class="getRankClass(scope.row.dailyRankings[date])">
|
||||
{{ scope.row.dailyRankings[date] || '-' }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>import { listKeywordItem ,todayRankStat} from "@/api/busi/keywordItem";
|
||||
|
||||
export default {
|
||||
name: "BusiKeywordItem",
|
||||
data() {
|
||||
// 计算默认日期范围:今天往前推30天
|
||||
const getDefaultDateRange = () => {
|
||||
const today = new Date();
|
||||
const thirtyDaysAgo = new Date(today);
|
||||
thirtyDaysAgo.setDate(today.getDate() - 30);
|
||||
|
||||
return [
|
||||
this.formatDate(thirtyDaysAgo),
|
||||
this.formatDate(today)
|
||||
];
|
||||
};
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 关键词表格数据
|
||||
keywordList: [],
|
||||
// 日期列表
|
||||
dateList: [],
|
||||
// 日期范围,默认为30天范围
|
||||
dateRange: getDefaultDateRange(),
|
||||
// 今日报表数据
|
||||
todayRankData: null,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
title: undefined,
|
||||
beginDate: undefined,
|
||||
endDate: undefined
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getTodayRankData();
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 获取今日报表数据 */
|
||||
getTodayRankData() {
|
||||
todayRankStat({}).then(response => {
|
||||
this.todayRankData = response.data;
|
||||
});
|
||||
},
|
||||
/** 查询列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
|
||||
// 检查日期范围是否超过30天
|
||||
if (this.dateRange && this.dateRange.length === 2) {
|
||||
const startDate = new Date(this.dateRange[0]);
|
||||
const endDate = new Date(this.dateRange[1]);
|
||||
|
||||
// 计算时间差(毫秒)
|
||||
const timeDiff = Math.abs(endDate.getTime() - startDate.getTime());
|
||||
// 转换为天数
|
||||
const diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
|
||||
|
||||
if (diffDays > 30) {
|
||||
this.$message.warning("查询时间范围不能超过30天");
|
||||
this.loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.queryParams.beginDate = this.dateRange[0];
|
||||
this.queryParams.endDate = this.dateRange[1];
|
||||
} else {
|
||||
this.queryParams.beginDate = undefined;
|
||||
this.queryParams.endDate = undefined;
|
||||
}
|
||||
|
||||
listKeywordItem(this.queryParams).then(response => {
|
||||
this.keywordList = response.data.records;
|
||||
this.total = response.data.total;
|
||||
|
||||
// 提取日期列表
|
||||
if (this.keywordList.length > 0) {
|
||||
this.dateList = Object.keys(this.keywordList[0].dailyRankings);
|
||||
} else {
|
||||
this.dateList = [];
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
// 重置为默认30天时间范围
|
||||
const today = new Date();
|
||||
const thirtyDaysAgo = new Date(today);
|
||||
thirtyDaysAgo.setDate(today.getDate() - 30);
|
||||
|
||||
this.dateRange = [
|
||||
this.formatDate(thirtyDaysAgo),
|
||||
this.formatDate(today)
|
||||
];
|
||||
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 获取排名样式 */
|
||||
getRankClass(ranking) {
|
||||
if (!ranking) return '';
|
||||
if (ranking <= 3) {
|
||||
return 'rank-top';
|
||||
} else if (ranking <= 10) {
|
||||
return 'rank-good';
|
||||
} else if (ranking <= 50) {
|
||||
return 'rank-normal';
|
||||
} else {
|
||||
return 'rank-bad';
|
||||
}
|
||||
},
|
||||
/** 格式化日期为 yyyy-MM-dd 格式 */
|
||||
formatDate(date) {
|
||||
const year = date.getFullYear();
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getDate().toString().padStart(2, '0');
|
||||
return `${year}-${month}-${day}`;
|
||||
},
|
||||
/** 格式化日期标签 */
|
||||
formatDateLabel(date) {
|
||||
if (!date) return '';
|
||||
const d = new Date(date);
|
||||
return (d.getMonth() + 1).toString().padStart(2, '0') + '-' +
|
||||
d.getDate().toString().padStart(2, '0');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.today-rank-summary {
|
||||
margin-bottom: 15px;
|
||||
padding: 10px;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
letter-spacing: 1px;
|
||||
span{
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
padding: 0 4px;
|
||||
}
|
||||
}
|
||||
.rank-top {
|
||||
color: #f56c6c;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.rank-good {
|
||||
color: #67c23a;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.rank-normal {
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
.rank-bad {
|
||||
color: #909399;
|
||||
}
|
||||
</style>
|
||||
@ -112,6 +112,14 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<template v-slot:label>
|
||||
<span>排序</span>
|
||||
<el-tooltip class="item" effect="dark" content="数字越大越靠前"
|
||||
placement="bottom"
|
||||
>
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="form.sort" type="number" placeholder="请输入排序"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -124,6 +132,14 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="页面keyword" prop="prodKeyword">
|
||||
<template v-slot:label>
|
||||
<span>页面keyword</span>
|
||||
<el-tooltip class="item" effect="dark" content="请确保多个关键词用英文逗号','隔开"
|
||||
placement="bottom"
|
||||
>
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="form.prodKeyword" type="textarea" placeholder="请输入页面keyword"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
@ -109,6 +109,14 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<template v-slot:label>
|
||||
<span>排序</span>
|
||||
<el-tooltip class="item" effect="dark" content="数字越大越靠前"
|
||||
placement="bottom"
|
||||
>
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="form.sort" type="number" placeholder="请输入排序"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -121,6 +129,14 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="页面keyword" prop="prodKeyword">
|
||||
<template v-slot:label>
|
||||
<span>页面keyword</span>
|
||||
<el-tooltip class="item" effect="dark" content="请确保多个关键词用英文逗号','隔开"
|
||||
placement="bottom"
|
||||
>
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input v-model="form.prodKeyword" type="textarea" placeholder="请输入页面keyword"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user