diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
index 348f2a0..4f41b58 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
@@ -5,14 +5,14 @@
-
+
- id, keys, search_time AS searchTime, keep_days AS keepDays
+ id, keywords, search_time AS searchTime, keep_days AS keepDays
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
index 348f2a0..4f41b58 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
@@ -5,14 +5,14 @@
-
+
- id, keys, search_time AS searchTime, keep_days AS keepDays
+ id, keywords, search_time AS searchTime, keep_days AS keepDays
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
new file mode 100644
index 0000000..df0766c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
@@ -0,0 +1,38 @@
+package com.casic.missiles.modular.system.job;
+
+import cn.hutool.core.util.RandomUtil;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import lombok.SneakyThrows;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+
+/**
+ * @ClassName QuartzJob
+ * @Description 依赖casic-job-quartz,并在CasicApplication上增加注解 @EnableScheduling
+ * @Author lwh
+ * @Date 2021/2/5 11:20
+ * @Version 1.0
+ */
+@Component
+public class QuartzJob {
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ *
+ */
+ @SneakyThrows
+ @Scheduled(cron = "0 0 10,14,16 * * ?")
+ public void execute() {
+ try {
+ Thread.sleep(RandomUtil.randomBigDecimal(new BigDecimal(2000)).intValue());
+ System.out.println("-----Thread ID 每60秒执行一次");
+ productInfoService.searchProducts(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
index 348f2a0..4f41b58 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
@@ -5,14 +5,14 @@
-
+
- id, keys, search_time AS searchTime, keep_days AS keepDays
+ id, keywords, search_time AS searchTime, keep_days AS keepDays
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
new file mode 100644
index 0000000..df0766c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
@@ -0,0 +1,38 @@
+package com.casic.missiles.modular.system.job;
+
+import cn.hutool.core.util.RandomUtil;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import lombok.SneakyThrows;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+
+/**
+ * @ClassName QuartzJob
+ * @Description 依赖casic-job-quartz,并在CasicApplication上增加注解 @EnableScheduling
+ * @Author lwh
+ * @Date 2021/2/5 11:20
+ * @Version 1.0
+ */
+@Component
+public class QuartzJob {
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ *
+ */
+ @SneakyThrows
+ @Scheduled(cron = "0 0 10,14,16 * * ?")
+ public void execute() {
+ try {
+ Thread.sleep(RandomUtil.randomBigDecimal(new BigDecimal(2000)).intValue());
+ System.out.println("-----Thread ID 每60秒执行一次");
+ productInfoService.searchProducts(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
index 03190bf..d5c4ecd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
@@ -1,14 +1,74 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
+import java.util.Date;
+
/**
- * 产品信息
+ *
+ * 商品信息
+ *
*
- * @author lenovo
+ * @author stylefeng123
+ * @since 2022-05-05
*/
@Data
-public class ProductInfo {
- private String description;
+@TableName("reptile_product_info")
+public class ProductInfo extends Model {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ private Long id;
+ /**
+ * 页面价格
+ */
+ @TableField("price")
private String price;
+ /**
+ * 满减价格
+ */
+ @TableField("actual_price")
+ private String actualPrice;
+ /**
+ * 优惠信息
+ */
+ @TableField("discount")
+ private String discount;
+
+ /**
+ * 其他信息
+ */
+ private String description;
+
+
+ @TableField("key_id")
+ private Long keyId;
+
+ /**
+ * 0 页面无效 1 价格偏高
+ */
+ private String flag;
+ @JSONField(serializeUsing = DateDeserializer.class)
+ @TableField("create_time")
+ private Date createTime;
+ @TableField(exist = false)
+ private String skuName;
+ @TableField(exist = false)
+ private String skuUrl;
+
+ @Override
+ public String toString() {
+ return "ProductInfo{" +
+ "id=" + id +
+ ", description=" + description +
+ "}";
+ }
}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
index 348f2a0..4f41b58 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
@@ -5,14 +5,14 @@
-
+
- id, keys, search_time AS searchTime, keep_days AS keepDays
+ id, keywords, search_time AS searchTime, keep_days AS keepDays
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
new file mode 100644
index 0000000..df0766c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
@@ -0,0 +1,38 @@
+package com.casic.missiles.modular.system.job;
+
+import cn.hutool.core.util.RandomUtil;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import lombok.SneakyThrows;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+
+/**
+ * @ClassName QuartzJob
+ * @Description 依赖casic-job-quartz,并在CasicApplication上增加注解 @EnableScheduling
+ * @Author lwh
+ * @Date 2021/2/5 11:20
+ * @Version 1.0
+ */
+@Component
+public class QuartzJob {
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ *
+ */
+ @SneakyThrows
+ @Scheduled(cron = "0 0 10,14,16 * * ?")
+ public void execute() {
+ try {
+ Thread.sleep(RandomUtil.randomBigDecimal(new BigDecimal(2000)).intValue());
+ System.out.println("-----Thread ID 每60秒执行一次");
+ productInfoService.searchProducts(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
index 03190bf..d5c4ecd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
@@ -1,14 +1,74 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
+import java.util.Date;
+
/**
- * 产品信息
+ *
+ * 商品信息
+ *
*
- * @author lenovo
+ * @author stylefeng123
+ * @since 2022-05-05
*/
@Data
-public class ProductInfo {
- private String description;
+@TableName("reptile_product_info")
+public class ProductInfo extends Model {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ private Long id;
+ /**
+ * 页面价格
+ */
+ @TableField("price")
private String price;
+ /**
+ * 满减价格
+ */
+ @TableField("actual_price")
+ private String actualPrice;
+ /**
+ * 优惠信息
+ */
+ @TableField("discount")
+ private String discount;
+
+ /**
+ * 其他信息
+ */
+ private String description;
+
+
+ @TableField("key_id")
+ private Long keyId;
+
+ /**
+ * 0 页面无效 1 价格偏高
+ */
+ private String flag;
+ @JSONField(serializeUsing = DateDeserializer.class)
+ @TableField("create_time")
+ private Date createTime;
+ @TableField(exist = false)
+ private String skuName;
+ @TableField(exist = false)
+ private String skuUrl;
+
+ @Override
+ public String toString() {
+ return "ProductInfo{" +
+ "id=" + id +
+ ", description=" + description +
+ "}";
+ }
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
index 09eb7ee..ed01581 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
@@ -1,8 +1,10 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
import java.util.Date;
@@ -26,12 +28,24 @@
*/
private Long id;
/**
- * 检索关键字
+ * 商品名称
*/
- private String keys;
+ @TableField("sku_name")
+ private String skuName;
+ /**
+ * 商品url
+ */
+ @TableField("sku_url")
+ private String skuUrl;
+ /**
+ * 设定价格
+ */
+ @TableField("price")
+ private String price;
/**
* 最后检索时间
*/
+ @JSONField(serializeUsing = DateDeserializer.class)
@TableField("search_time")
private Date searchTime;
/**
@@ -40,12 +54,10 @@
@TableField("keep_days")
private Integer keepDays;
-
@Override
public String toString() {
return "SearchKeys{" +
"id=" + id +
- ", keys=" + keys +
", searchTime=" + searchTime +
", keepDays=" + keepDays +
"}";
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
index 348f2a0..4f41b58 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
@@ -5,14 +5,14 @@
-
+
- id, keys, search_time AS searchTime, keep_days AS keepDays
+ id, keywords, search_time AS searchTime, keep_days AS keepDays
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
new file mode 100644
index 0000000..df0766c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
@@ -0,0 +1,38 @@
+package com.casic.missiles.modular.system.job;
+
+import cn.hutool.core.util.RandomUtil;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import lombok.SneakyThrows;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+
+/**
+ * @ClassName QuartzJob
+ * @Description 依赖casic-job-quartz,并在CasicApplication上增加注解 @EnableScheduling
+ * @Author lwh
+ * @Date 2021/2/5 11:20
+ * @Version 1.0
+ */
+@Component
+public class QuartzJob {
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ *
+ */
+ @SneakyThrows
+ @Scheduled(cron = "0 0 10,14,16 * * ?")
+ public void execute() {
+ try {
+ Thread.sleep(RandomUtil.randomBigDecimal(new BigDecimal(2000)).intValue());
+ System.out.println("-----Thread ID 每60秒执行一次");
+ productInfoService.searchProducts(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
index 03190bf..d5c4ecd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
@@ -1,14 +1,74 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
+import java.util.Date;
+
/**
- * 产品信息
+ *
+ * 商品信息
+ *
*
- * @author lenovo
+ * @author stylefeng123
+ * @since 2022-05-05
*/
@Data
-public class ProductInfo {
- private String description;
+@TableName("reptile_product_info")
+public class ProductInfo extends Model {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ private Long id;
+ /**
+ * 页面价格
+ */
+ @TableField("price")
private String price;
+ /**
+ * 满减价格
+ */
+ @TableField("actual_price")
+ private String actualPrice;
+ /**
+ * 优惠信息
+ */
+ @TableField("discount")
+ private String discount;
+
+ /**
+ * 其他信息
+ */
+ private String description;
+
+
+ @TableField("key_id")
+ private Long keyId;
+
+ /**
+ * 0 页面无效 1 价格偏高
+ */
+ private String flag;
+ @JSONField(serializeUsing = DateDeserializer.class)
+ @TableField("create_time")
+ private Date createTime;
+ @TableField(exist = false)
+ private String skuName;
+ @TableField(exist = false)
+ private String skuUrl;
+
+ @Override
+ public String toString() {
+ return "ProductInfo{" +
+ "id=" + id +
+ ", description=" + description +
+ "}";
+ }
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
index 09eb7ee..ed01581 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
@@ -1,8 +1,10 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
import java.util.Date;
@@ -26,12 +28,24 @@
*/
private Long id;
/**
- * 检索关键字
+ * 商品名称
*/
- private String keys;
+ @TableField("sku_name")
+ private String skuName;
+ /**
+ * 商品url
+ */
+ @TableField("sku_url")
+ private String skuUrl;
+ /**
+ * 设定价格
+ */
+ @TableField("price")
+ private String price;
/**
* 最后检索时间
*/
+ @JSONField(serializeUsing = DateDeserializer.class)
@TableField("search_time")
private Date searchTime;
/**
@@ -40,12 +54,10 @@
@TableField("keep_days")
private Integer keepDays;
-
@Override
public String toString() {
return "SearchKeys{" +
"id=" + id +
- ", keys=" + keys +
", searchTime=" + searchTime +
", keepDays=" + keepDays +
"}";
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
new file mode 100644
index 0000000..f6a8a35
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
@@ -0,0 +1,30 @@
+package com.casic.missiles.modular.system.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.casic.missiles.modular.system.model.ProductInfo;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 服务类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface IProductInfoService extends IService {
+ /**
+ * 检索商品接口定义
+ * @param type jd tm
+ * @return
+ */
+ public List searchProducts(String type);
+ /**
+ * 检索商品价格信息
+ * @param type jd tm
+ * @return
+ */
+ public List searchDbProductPricePage(String type, Page page);
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
index 348f2a0..4f41b58 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
@@ -5,14 +5,14 @@
-
+
- id, keys, search_time AS searchTime, keep_days AS keepDays
+ id, keywords, search_time AS searchTime, keep_days AS keepDays
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
new file mode 100644
index 0000000..df0766c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
@@ -0,0 +1,38 @@
+package com.casic.missiles.modular.system.job;
+
+import cn.hutool.core.util.RandomUtil;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import lombok.SneakyThrows;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+
+/**
+ * @ClassName QuartzJob
+ * @Description 依赖casic-job-quartz,并在CasicApplication上增加注解 @EnableScheduling
+ * @Author lwh
+ * @Date 2021/2/5 11:20
+ * @Version 1.0
+ */
+@Component
+public class QuartzJob {
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ *
+ */
+ @SneakyThrows
+ @Scheduled(cron = "0 0 10,14,16 * * ?")
+ public void execute() {
+ try {
+ Thread.sleep(RandomUtil.randomBigDecimal(new BigDecimal(2000)).intValue());
+ System.out.println("-----Thread ID 每60秒执行一次");
+ productInfoService.searchProducts(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
index 03190bf..d5c4ecd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
@@ -1,14 +1,74 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
+import java.util.Date;
+
/**
- * 产品信息
+ *
+ * 商品信息
+ *
*
- * @author lenovo
+ * @author stylefeng123
+ * @since 2022-05-05
*/
@Data
-public class ProductInfo {
- private String description;
+@TableName("reptile_product_info")
+public class ProductInfo extends Model {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ private Long id;
+ /**
+ * 页面价格
+ */
+ @TableField("price")
private String price;
+ /**
+ * 满减价格
+ */
+ @TableField("actual_price")
+ private String actualPrice;
+ /**
+ * 优惠信息
+ */
+ @TableField("discount")
+ private String discount;
+
+ /**
+ * 其他信息
+ */
+ private String description;
+
+
+ @TableField("key_id")
+ private Long keyId;
+
+ /**
+ * 0 页面无效 1 价格偏高
+ */
+ private String flag;
+ @JSONField(serializeUsing = DateDeserializer.class)
+ @TableField("create_time")
+ private Date createTime;
+ @TableField(exist = false)
+ private String skuName;
+ @TableField(exist = false)
+ private String skuUrl;
+
+ @Override
+ public String toString() {
+ return "ProductInfo{" +
+ "id=" + id +
+ ", description=" + description +
+ "}";
+ }
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
index 09eb7ee..ed01581 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
@@ -1,8 +1,10 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
import java.util.Date;
@@ -26,12 +28,24 @@
*/
private Long id;
/**
- * 检索关键字
+ * 商品名称
*/
- private String keys;
+ @TableField("sku_name")
+ private String skuName;
+ /**
+ * 商品url
+ */
+ @TableField("sku_url")
+ private String skuUrl;
+ /**
+ * 设定价格
+ */
+ @TableField("price")
+ private String price;
/**
* 最后检索时间
*/
+ @JSONField(serializeUsing = DateDeserializer.class)
@TableField("search_time")
private Date searchTime;
/**
@@ -40,12 +54,10 @@
@TableField("keep_days")
private Integer keepDays;
-
@Override
public String toString() {
return "SearchKeys{" +
"id=" + id +
- ", keys=" + keys +
", searchTime=" + searchTime +
", keepDays=" + keepDays +
"}";
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
new file mode 100644
index 0000000..f6a8a35
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
@@ -0,0 +1,30 @@
+package com.casic.missiles.modular.system.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.casic.missiles.modular.system.model.ProductInfo;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 服务类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface IProductInfoService extends IService {
+ /**
+ * 检索商品接口定义
+ * @param type jd tm
+ * @return
+ */
+ public List searchProducts(String type);
+ /**
+ * 检索商品价格信息
+ * @param type jd tm
+ * @return
+ */
+ public List searchDbProductPricePage(String type, Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java
new file mode 100644
index 0000000..e912cfd
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java
@@ -0,0 +1,218 @@
+package com.casic.missiles.modular.system.service.impl;
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.casic.missiles.modular.system.dao.ProductInfoMapper;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import lombok.SneakyThrows;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeOptions;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ *
+ * 商品信息 服务实现类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+@Service
+public class ProductInfoServiceImpl extends ServiceImpl implements IProductInfoService {
+ @Value("${casic.webdriver.path}")
+ private String path;
+ @Value("${casic.tm.account}")
+ private String account;
+ @Value("${casic.tm.pwd}")
+ private String pwd;
+ @Resource
+ private ISearchKeysService searchKeysService;
+
+ @Override
+ public List searchProducts(String type) {
+ System.setProperty("webdriver.chrome.driver", path);
+ List searchKeys = searchKeysService.list();
+ Date searchTime = new Date();
+ WebDriver webDriver = null;
+ try {
+ //驱动地址
+ ChromeOptions option = new ChromeOptions();
+ //去掉chrome 正受到自动测试软件的控制
+ option.addArguments("disable-infobars");
+ //开启开发者模式
+ option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
+ option.addArguments("--disable-blink-features");
+ option.addArguments("--disable-blink-features=AutomationControlled");
+ //初始化一个chrome浏览器实例
+ webDriver = new ChromeDriver(option);
+ //最大化窗口
+ webDriver.manage().window().maximize();
+ //设置隐性等待时间
+ webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
+ for (SearchKeys searchKey : searchKeys) {
+// List productInfos = searchJdProducts(webDriver, searchKey.getKeywords());
+// ProductInfo maxJd = productInfos.stream().max(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// ProductInfo minJd = productInfos.stream().min(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// // 过滤价格区间
+// ProductInfo info = new ProductInfo();
+// info.setKeyId(searchKey.getId());
+// info.setCreateTime(searchTime);
+// info.setMaxPrice(maxJd.getMaxPrice());
+// info.setMinPrice(minJd.getMaxPrice());
+// StringBuilder jdStr = new StringBuilder();
+// jdStr.append("京东:").append(minJd.getDescription()).append("---").append(maxJd.getDescription()).append(" ");
+// // 过滤天猫信息
+// List productTmInfos = searchTbProducts(webDriver, searchKey.getKeywords());
+// ProductInfo maxTb = productTmInfos.stream().max(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// ProductInfo minTb = productTmInfos.stream().min(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// info.setMaxTmPrice(maxTb.getMaxPrice());
+// info.setMinTmPrice(minTb.getMaxPrice());
+// jdStr.append("天猫:").append(minTb.getDescription()).append("---").append(maxTb.getDescription()).append(" ");
+
+// info.setDescription(jdStr.toString());
+// this.save(info);
+ searchKey.setSearchTime(searchTime);
+ searchKeysService.updateById(searchKey);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (webDriver != null) {
+ webDriver.close();
+ webDriver.quit();
+ }
+ }
+ return new ArrayList<>();
+ }
+
+ @Override
+ public List searchDbProductPricePage(String keywords, Page page) {
+ return this.baseMapper.searchDbProductPricePage(keywords, page);
+ }
+
+ private ProductInfo searchJdDetail(WebDriver webDriver, String url) {
+ ProductInfo productInfo = new ProductInfo();
+ //打开京东地址
+ webDriver.get(url);
+ String title = webDriver.getTitle();
+ WebElement skuEl = webDriver.findElement(By.className("sku-name"));
+ if (skuEl != null) {
+ String skuName = skuEl.getText();
+ productInfo.setDescription(skuName);
+ } else {
+ productInfo.setFlag("1");
+ }
+
+ // NO1 读取价格信息
+ WebElement priceEl = webDriver.findElement(By.className("p-price"));
+ if (priceEl != null) {
+ WebElement webP = priceEl.findElement(By.className("price"));
+ if (webP != null && NumberUtil.isNumber(webP.getText())) {
+ //设置页面价格
+ productInfo.setPrice(webP.getText());
+ } else {
+ //页面元素获取异常 判定为页面失效
+ productInfo.setFlag("1");
+ }
+ } else {
+ //页面元素获取异常 判定为页面失效
+ productInfo.setFlag("1");
+ }
+
+ // NO2 读取打折信息
+ WebElement promItem = webDriver.findElement(By.className("prom-item"));
+ if (promItem != null) {
+ //提取满减信息
+ WebElement redElm = promItem.findElement(By.className("hl_red"));
+ String text = redElm.getText();
+ if (StrUtil.isNotEmpty(text)) {
+ //提取满减
+ String bg = promItem.findElement(By.className("hl_red_bg")).getText();
+ String reg = "[\\u4E00-\\u9FA5]+";
+ List list = Stream.of(reg.split(reg)).filter(StrUtil::isNotEmpty).collect(Collectors.toList());
+ if (list.size() > 0 && list.stream().anyMatch(NumberUtil::isNumber)) {
+ //计算满减价格
+ //判断价格是否符合满减数
+ if ("满减".equals(bg) && list.size() > 2) {
+ BigDecimal skuPrice = NumberUtil.toBigDecimal(productInfo.getPrice());
+ if (skuPrice.compareTo(NumberUtil.toBigDecimal(list.get(0))) >= 0) {
+ BigDecimal discountPrice = NumberUtil.toBigDecimal(list.get(1));
+ //设置实际价格
+ productInfo.setActualPrice(skuPrice.subtract(discountPrice).toString());
+ }
+ }
+ }
+ }
+ }
+
+ return productInfo;
+ }
+
+ private List searchJdProducts(WebDriver webDriver, String keywords) {
+ //打开京东地址
+ webDriver.get("https://search.jd.com/Search?keyword=" + keywords);
+ String title = webDriver.getTitle();
+ List elementList = webDriver.findElements(By.className("gl-i-wrap"));
+ List productInfos = elementList.stream().map(webElement -> {
+ ProductInfo productInfo = new ProductInfo();
+ productInfo.setDescription(webElement.findElement(By.className("p-name")).getText());
+ String price = webElement.findElement(By.className("p-price")).getText();
+ price = price.replaceAll("¥", "");
+// productInfo.setMaxPrice(price);
+ return productInfo;
+ }).collect(Collectors.toList());
+ return productInfos;
+ }
+
+ @SneakyThrows
+ private List searchTbProducts(WebDriver webDriver, String keyWords) {
+ //打开京东地址
+ webDriver.get("https://login.taobao.com/member/login.jhtml?tpl_redirect_url=https%3A%2F%2Fwww.tmall.com&style=miniall&enup=true&newMini2=true&full_redirect=true&sub=true&from=tmall&allp=assets_css%3D3.0.10/login_pc.css&pms=1650640249767");
+ Thread.sleep(10 * 1000L);
+
+ // 预登录
+ webDriver.findElement(By.xpath("//input[@name='fm-login-id']")).sendKeys(account);
+ webDriver.findElement(By.xpath("//input[@name='fm-login-password']")).sendKeys(pwd);
+ webDriver.findElement(By.xpath("//*[@class=\"fm-button fm-submit password-login\"]")).click();
+
+ String oldHandler = webDriver.getWindowHandle();
+ webDriver.findElement(By.className("SearchInput--searchInputContent--1USWNEl")).sendKeys(keyWords);
+ Thread.sleep(10 * 1000L);
+ webDriver.findElement(By.className("SearchInput--searchButton--1Sz2UIn")).click();
+ Thread.sleep(30 * 1000L);
+ // 获取当前handler
+
+ Set sets = webDriver.getWindowHandles();
+ String newWindow = sets.stream().filter(handler -> !oldHandler.equals(handler)).findFirst().get();
+ webDriver.switchTo().window(newWindow);
+
+ List tmElementList = webDriver.findElements(By.className("product-iWrap"));
+ List productInfos = tmElementList.stream().map(pElement -> {
+ ProductInfo productInfo = new ProductInfo();
+ productInfo.setDescription(pElement.findElement(By.className("productTitle")).getText());
+ String price = pElement.findElement(By.className("productPrice")).getText();
+ System.out.println(price);
+ price = price.replaceAll("¥", "");
+// productInfo.setMaxPrice(price);
+ return productInfo;
+ }).collect(Collectors.toList());
+ return productInfos;
+ }
+}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
index 348f2a0..4f41b58 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
@@ -5,14 +5,14 @@
-
+
- id, keys, search_time AS searchTime, keep_days AS keepDays
+ id, keywords, search_time AS searchTime, keep_days AS keepDays
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
new file mode 100644
index 0000000..df0766c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
@@ -0,0 +1,38 @@
+package com.casic.missiles.modular.system.job;
+
+import cn.hutool.core.util.RandomUtil;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import lombok.SneakyThrows;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+
+/**
+ * @ClassName QuartzJob
+ * @Description 依赖casic-job-quartz,并在CasicApplication上增加注解 @EnableScheduling
+ * @Author lwh
+ * @Date 2021/2/5 11:20
+ * @Version 1.0
+ */
+@Component
+public class QuartzJob {
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ *
+ */
+ @SneakyThrows
+ @Scheduled(cron = "0 0 10,14,16 * * ?")
+ public void execute() {
+ try {
+ Thread.sleep(RandomUtil.randomBigDecimal(new BigDecimal(2000)).intValue());
+ System.out.println("-----Thread ID 每60秒执行一次");
+ productInfoService.searchProducts(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
index 03190bf..d5c4ecd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
@@ -1,14 +1,74 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
+import java.util.Date;
+
/**
- * 产品信息
+ *
+ * 商品信息
+ *
*
- * @author lenovo
+ * @author stylefeng123
+ * @since 2022-05-05
*/
@Data
-public class ProductInfo {
- private String description;
+@TableName("reptile_product_info")
+public class ProductInfo extends Model {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ private Long id;
+ /**
+ * 页面价格
+ */
+ @TableField("price")
private String price;
+ /**
+ * 满减价格
+ */
+ @TableField("actual_price")
+ private String actualPrice;
+ /**
+ * 优惠信息
+ */
+ @TableField("discount")
+ private String discount;
+
+ /**
+ * 其他信息
+ */
+ private String description;
+
+
+ @TableField("key_id")
+ private Long keyId;
+
+ /**
+ * 0 页面无效 1 价格偏高
+ */
+ private String flag;
+ @JSONField(serializeUsing = DateDeserializer.class)
+ @TableField("create_time")
+ private Date createTime;
+ @TableField(exist = false)
+ private String skuName;
+ @TableField(exist = false)
+ private String skuUrl;
+
+ @Override
+ public String toString() {
+ return "ProductInfo{" +
+ "id=" + id +
+ ", description=" + description +
+ "}";
+ }
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
index 09eb7ee..ed01581 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
@@ -1,8 +1,10 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
import java.util.Date;
@@ -26,12 +28,24 @@
*/
private Long id;
/**
- * 检索关键字
+ * 商品名称
*/
- private String keys;
+ @TableField("sku_name")
+ private String skuName;
+ /**
+ * 商品url
+ */
+ @TableField("sku_url")
+ private String skuUrl;
+ /**
+ * 设定价格
+ */
+ @TableField("price")
+ private String price;
/**
* 最后检索时间
*/
+ @JSONField(serializeUsing = DateDeserializer.class)
@TableField("search_time")
private Date searchTime;
/**
@@ -40,12 +54,10 @@
@TableField("keep_days")
private Integer keepDays;
-
@Override
public String toString() {
return "SearchKeys{" +
"id=" + id +
- ", keys=" + keys +
", searchTime=" + searchTime +
", keepDays=" + keepDays +
"}";
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
new file mode 100644
index 0000000..f6a8a35
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
@@ -0,0 +1,30 @@
+package com.casic.missiles.modular.system.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.casic.missiles.modular.system.model.ProductInfo;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 服务类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface IProductInfoService extends IService {
+ /**
+ * 检索商品接口定义
+ * @param type jd tm
+ * @return
+ */
+ public List searchProducts(String type);
+ /**
+ * 检索商品价格信息
+ * @param type jd tm
+ * @return
+ */
+ public List searchDbProductPricePage(String type, Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java
new file mode 100644
index 0000000..e912cfd
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java
@@ -0,0 +1,218 @@
+package com.casic.missiles.modular.system.service.impl;
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.casic.missiles.modular.system.dao.ProductInfoMapper;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import lombok.SneakyThrows;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeOptions;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ *
+ * 商品信息 服务实现类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+@Service
+public class ProductInfoServiceImpl extends ServiceImpl implements IProductInfoService {
+ @Value("${casic.webdriver.path}")
+ private String path;
+ @Value("${casic.tm.account}")
+ private String account;
+ @Value("${casic.tm.pwd}")
+ private String pwd;
+ @Resource
+ private ISearchKeysService searchKeysService;
+
+ @Override
+ public List searchProducts(String type) {
+ System.setProperty("webdriver.chrome.driver", path);
+ List searchKeys = searchKeysService.list();
+ Date searchTime = new Date();
+ WebDriver webDriver = null;
+ try {
+ //驱动地址
+ ChromeOptions option = new ChromeOptions();
+ //去掉chrome 正受到自动测试软件的控制
+ option.addArguments("disable-infobars");
+ //开启开发者模式
+ option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
+ option.addArguments("--disable-blink-features");
+ option.addArguments("--disable-blink-features=AutomationControlled");
+ //初始化一个chrome浏览器实例
+ webDriver = new ChromeDriver(option);
+ //最大化窗口
+ webDriver.manage().window().maximize();
+ //设置隐性等待时间
+ webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
+ for (SearchKeys searchKey : searchKeys) {
+// List productInfos = searchJdProducts(webDriver, searchKey.getKeywords());
+// ProductInfo maxJd = productInfos.stream().max(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// ProductInfo minJd = productInfos.stream().min(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// // 过滤价格区间
+// ProductInfo info = new ProductInfo();
+// info.setKeyId(searchKey.getId());
+// info.setCreateTime(searchTime);
+// info.setMaxPrice(maxJd.getMaxPrice());
+// info.setMinPrice(minJd.getMaxPrice());
+// StringBuilder jdStr = new StringBuilder();
+// jdStr.append("京东:").append(minJd.getDescription()).append("---").append(maxJd.getDescription()).append(" ");
+// // 过滤天猫信息
+// List productTmInfos = searchTbProducts(webDriver, searchKey.getKeywords());
+// ProductInfo maxTb = productTmInfos.stream().max(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// ProductInfo minTb = productTmInfos.stream().min(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// info.setMaxTmPrice(maxTb.getMaxPrice());
+// info.setMinTmPrice(minTb.getMaxPrice());
+// jdStr.append("天猫:").append(minTb.getDescription()).append("---").append(maxTb.getDescription()).append(" ");
+
+// info.setDescription(jdStr.toString());
+// this.save(info);
+ searchKey.setSearchTime(searchTime);
+ searchKeysService.updateById(searchKey);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (webDriver != null) {
+ webDriver.close();
+ webDriver.quit();
+ }
+ }
+ return new ArrayList<>();
+ }
+
+ @Override
+ public List searchDbProductPricePage(String keywords, Page page) {
+ return this.baseMapper.searchDbProductPricePage(keywords, page);
+ }
+
+ private ProductInfo searchJdDetail(WebDriver webDriver, String url) {
+ ProductInfo productInfo = new ProductInfo();
+ //打开京东地址
+ webDriver.get(url);
+ String title = webDriver.getTitle();
+ WebElement skuEl = webDriver.findElement(By.className("sku-name"));
+ if (skuEl != null) {
+ String skuName = skuEl.getText();
+ productInfo.setDescription(skuName);
+ } else {
+ productInfo.setFlag("1");
+ }
+
+ // NO1 读取价格信息
+ WebElement priceEl = webDriver.findElement(By.className("p-price"));
+ if (priceEl != null) {
+ WebElement webP = priceEl.findElement(By.className("price"));
+ if (webP != null && NumberUtil.isNumber(webP.getText())) {
+ //设置页面价格
+ productInfo.setPrice(webP.getText());
+ } else {
+ //页面元素获取异常 判定为页面失效
+ productInfo.setFlag("1");
+ }
+ } else {
+ //页面元素获取异常 判定为页面失效
+ productInfo.setFlag("1");
+ }
+
+ // NO2 读取打折信息
+ WebElement promItem = webDriver.findElement(By.className("prom-item"));
+ if (promItem != null) {
+ //提取满减信息
+ WebElement redElm = promItem.findElement(By.className("hl_red"));
+ String text = redElm.getText();
+ if (StrUtil.isNotEmpty(text)) {
+ //提取满减
+ String bg = promItem.findElement(By.className("hl_red_bg")).getText();
+ String reg = "[\\u4E00-\\u9FA5]+";
+ List list = Stream.of(reg.split(reg)).filter(StrUtil::isNotEmpty).collect(Collectors.toList());
+ if (list.size() > 0 && list.stream().anyMatch(NumberUtil::isNumber)) {
+ //计算满减价格
+ //判断价格是否符合满减数
+ if ("满减".equals(bg) && list.size() > 2) {
+ BigDecimal skuPrice = NumberUtil.toBigDecimal(productInfo.getPrice());
+ if (skuPrice.compareTo(NumberUtil.toBigDecimal(list.get(0))) >= 0) {
+ BigDecimal discountPrice = NumberUtil.toBigDecimal(list.get(1));
+ //设置实际价格
+ productInfo.setActualPrice(skuPrice.subtract(discountPrice).toString());
+ }
+ }
+ }
+ }
+ }
+
+ return productInfo;
+ }
+
+ private List searchJdProducts(WebDriver webDriver, String keywords) {
+ //打开京东地址
+ webDriver.get("https://search.jd.com/Search?keyword=" + keywords);
+ String title = webDriver.getTitle();
+ List elementList = webDriver.findElements(By.className("gl-i-wrap"));
+ List productInfos = elementList.stream().map(webElement -> {
+ ProductInfo productInfo = new ProductInfo();
+ productInfo.setDescription(webElement.findElement(By.className("p-name")).getText());
+ String price = webElement.findElement(By.className("p-price")).getText();
+ price = price.replaceAll("¥", "");
+// productInfo.setMaxPrice(price);
+ return productInfo;
+ }).collect(Collectors.toList());
+ return productInfos;
+ }
+
+ @SneakyThrows
+ private List searchTbProducts(WebDriver webDriver, String keyWords) {
+ //打开京东地址
+ webDriver.get("https://login.taobao.com/member/login.jhtml?tpl_redirect_url=https%3A%2F%2Fwww.tmall.com&style=miniall&enup=true&newMini2=true&full_redirect=true&sub=true&from=tmall&allp=assets_css%3D3.0.10/login_pc.css&pms=1650640249767");
+ Thread.sleep(10 * 1000L);
+
+ // 预登录
+ webDriver.findElement(By.xpath("//input[@name='fm-login-id']")).sendKeys(account);
+ webDriver.findElement(By.xpath("//input[@name='fm-login-password']")).sendKeys(pwd);
+ webDriver.findElement(By.xpath("//*[@class=\"fm-button fm-submit password-login\"]")).click();
+
+ String oldHandler = webDriver.getWindowHandle();
+ webDriver.findElement(By.className("SearchInput--searchInputContent--1USWNEl")).sendKeys(keyWords);
+ Thread.sleep(10 * 1000L);
+ webDriver.findElement(By.className("SearchInput--searchButton--1Sz2UIn")).click();
+ Thread.sleep(30 * 1000L);
+ // 获取当前handler
+
+ Set sets = webDriver.getWindowHandles();
+ String newWindow = sets.stream().filter(handler -> !oldHandler.equals(handler)).findFirst().get();
+ webDriver.switchTo().window(newWindow);
+
+ List tmElementList = webDriver.findElements(By.className("product-iWrap"));
+ List productInfos = tmElementList.stream().map(pElement -> {
+ ProductInfo productInfo = new ProductInfo();
+ productInfo.setDescription(pElement.findElement(By.className("productTitle")).getText());
+ String price = pElement.findElement(By.className("productPrice")).getText();
+ System.out.println(price);
+ price = price.replaceAll("¥", "");
+// productInfo.setMaxPrice(price);
+ return productInfo;
+ }).collect(Collectors.toList());
+ return productInfos;
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductServiceImpl.java
deleted file mode 100644
index 4e72150..0000000
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductServiceImpl.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.casic.missiles.modular.system.service.impl;
-
-import com.casic.missiles.modular.system.model.ProductInfo;
-import com.casic.missiles.modular.system.service.IProductSearchService;
-import lombok.SneakyThrows;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.chrome.ChromeDriver;
-import org.openqa.selenium.chrome.ChromeOptions;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-/**
- * 产品搜索实例
- *
- * @author lwh
- */
-@Component
-public class ProductServiceImpl implements IProductSearchService {
- @Value("${casic.webdriver.path}")
- private String path;
- @Override
- public List searchProducts(String type) {
- //驱动地址
- String chromedriver = "D:\\dev-soft\\seleuim-chmod\\chromedriver.exe";
- System.setProperty("webdriver.chrome.driver", path);
- ChromeOptions option = new ChromeOptions();
- //去掉chrome 正受到自动测试软件的控制
- option.addArguments("disable-infobars");
- //开启开发者模式
- option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
- option.addArguments("--disable-blink-features");
- option.addArguments("--disable-blink-features=AutomationControlled");
- //初始化一个chrome浏览器实例
- WebDriver webDriver = new ChromeDriver(option);
- //最大化窗口
- webDriver.manage().window().maximize();
- //设置隐性等待时间
- webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
-
- return searchJdProducts(webDriver);
- }
-
- private List searchJdProducts(WebDriver webDriver) {
- //打开京东地址
- webDriver.get("https://search.jd.com/Search?keyword=%E8%8B%B9%E6%9E%9C13");
- String title = webDriver.getTitle();
- List elementList = webDriver.findElements(By.className("gl-i-wrap"));
- List productInfos = elementList.stream().map(webElement -> {
- ProductInfo productInfo = new ProductInfo();
- productInfo.setDescription(webElement.findElement(By.className("p-name")).getText());
- productInfo.setPrice(webElement.findElement(By.className("p-price")).getText());
- return productInfo;
- }).collect(Collectors.toList());
- return productInfos;
- }
-
- @SneakyThrows
- private List searchTbProducts(WebDriver webDriver) {
- //打开京东地址
- webDriver.get("https://login.taobao.com/member/login.jhtml?tpl_redirect_url=https%3A%2F%2Fwww.tmall.com&style=miniall&enup=true&newMini2=true&full_redirect=true&sub=true&from=tmall&allp=assets_css%3D3.0.10/login_pc.css&pms=1650640249767");
- Thread.sleep(10 * 1000L);
-
- // 预登录
- webDriver.findElement(By.xpath("//input[@name='fm-login-id']")).sendKeys("18600202639");
- webDriver.findElement(By.xpath("//input[@name='fm-login-password']")).sendKeys("19881126yu");
- webDriver.findElement(By.xpath("//*[@class=\"fm-button fm-submit password-login\"]")).click();
-
- String oldHandler = webDriver.getWindowHandle();
- webDriver.findElement(By.className("SearchInput--searchInputContent--1USWNEl")).sendKeys("苹果13");
- Thread.sleep(10 * 1000L);
- webDriver.findElement(By.className("SearchInput--searchButton--1Sz2UIn")).click();
- Thread.sleep(30 * 1000L);
- // 获取当前handler
-
- Set sets = webDriver.getWindowHandles();
- String newWindow = sets.stream().filter(handler -> !oldHandler.equals(handler)).findFirst().get();
- webDriver.switchTo().window(newWindow);
-
- List tmElementList = webDriver.findElements(By.className("product-iWrap"));
- List productInfos = tmElementList.stream().map(pElement -> {
- ProductInfo productInfo = new ProductInfo();
- productInfo.setDescription(pElement.findElement(By.className("productPrice")).getText());
- productInfo.setPrice(pElement.findElement(By.className("productTitle")).getText());
- return productInfo;
- }).collect(Collectors.toList());
- return productInfos;
- }
-
- public static void main(String[] args) throws InterruptedException {
- //驱动地址
- String chromedriver = "D:\\dev-soft\\seleuim-chmod\\chromedriver.exe";
- System.setProperty("webdriver.chrome.driver", chromedriver);
- ChromeOptions option = new ChromeOptions();
- //去掉chrome 正受到自动测试软件的控制
- option.addArguments("disable-infobars");
- //开启开发者模式
- option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
- option.addArguments("--disable-blink-features");
- option.addArguments("--disable-blink-features=AutomationControlled");
- //初始化一个chrome浏览器实例
- WebDriver webDriver = new ChromeDriver(option);
- //最大化窗口
- webDriver.manage().window().maximize();
- //设置隐性等待时间
- webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
- //打开京东地址
- webDriver.get("https://login.taobao.com/member/login.jhtml?tpl_redirect_url=https%3A%2F%2Fwww.tmall.com&style=miniall&enup=true&newMini2=true&full_redirect=true&sub=true&from=tmall&allp=assets_css%3D3.0.10/login_pc.css&pms=1650640249767");
- Thread.sleep(10 * 1000L);
-
- // 预登录
- webDriver.findElement(By.xpath("//input[@name='fm-login-id']")).sendKeys("18600202639");
- webDriver.findElement(By.xpath("//input[@name='fm-login-password']")).sendKeys("19881126yu");
- webDriver.findElement(By.xpath("//*[@class=\"fm-button fm-submit password-login\"]")).click();
-
- String oldHandler = webDriver.getWindowHandle();
- webDriver.findElement(By.className("SearchInput--searchInputContent--1USWNEl")).sendKeys("苹果13");
- Thread.sleep(10 * 1000L);
- webDriver.findElement(By.className("SearchInput--searchButton--1Sz2UIn")).click();
- Thread.sleep(30 * 1000L);
- // 获取当前handler
-
- Set sets = webDriver.getWindowHandles();
- String newWindow = sets.stream().filter(handler -> !oldHandler.equals(handler)).findFirst().get();
- webDriver.switchTo().window(newWindow);
-
- List tmElementList = webDriver.findElements(By.className("product-iWrap"));
- List productInfos = tmElementList.stream().map(pElement -> {
- ProductInfo productInfo = new ProductInfo();
- productInfo.setDescription(pElement.findElement(By.className("productPrice")).getText());
- productInfo.setPrice(pElement.findElement(By.className("productTitle")).getText());
- return productInfo;
- }).collect(Collectors.toList());
-
- System.out.println(productInfos);
- }
-}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
index 348f2a0..4f41b58 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
@@ -5,14 +5,14 @@
-
+
- id, keys, search_time AS searchTime, keep_days AS keepDays
+ id, keywords, search_time AS searchTime, keep_days AS keepDays
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
new file mode 100644
index 0000000..df0766c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
@@ -0,0 +1,38 @@
+package com.casic.missiles.modular.system.job;
+
+import cn.hutool.core.util.RandomUtil;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import lombok.SneakyThrows;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+
+/**
+ * @ClassName QuartzJob
+ * @Description 依赖casic-job-quartz,并在CasicApplication上增加注解 @EnableScheduling
+ * @Author lwh
+ * @Date 2021/2/5 11:20
+ * @Version 1.0
+ */
+@Component
+public class QuartzJob {
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ *
+ */
+ @SneakyThrows
+ @Scheduled(cron = "0 0 10,14,16 * * ?")
+ public void execute() {
+ try {
+ Thread.sleep(RandomUtil.randomBigDecimal(new BigDecimal(2000)).intValue());
+ System.out.println("-----Thread ID 每60秒执行一次");
+ productInfoService.searchProducts(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
index 03190bf..d5c4ecd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
@@ -1,14 +1,74 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
+import java.util.Date;
+
/**
- * 产品信息
+ *
+ * 商品信息
+ *
*
- * @author lenovo
+ * @author stylefeng123
+ * @since 2022-05-05
*/
@Data
-public class ProductInfo {
- private String description;
+@TableName("reptile_product_info")
+public class ProductInfo extends Model {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ private Long id;
+ /**
+ * 页面价格
+ */
+ @TableField("price")
private String price;
+ /**
+ * 满减价格
+ */
+ @TableField("actual_price")
+ private String actualPrice;
+ /**
+ * 优惠信息
+ */
+ @TableField("discount")
+ private String discount;
+
+ /**
+ * 其他信息
+ */
+ private String description;
+
+
+ @TableField("key_id")
+ private Long keyId;
+
+ /**
+ * 0 页面无效 1 价格偏高
+ */
+ private String flag;
+ @JSONField(serializeUsing = DateDeserializer.class)
+ @TableField("create_time")
+ private Date createTime;
+ @TableField(exist = false)
+ private String skuName;
+ @TableField(exist = false)
+ private String skuUrl;
+
+ @Override
+ public String toString() {
+ return "ProductInfo{" +
+ "id=" + id +
+ ", description=" + description +
+ "}";
+ }
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
index 09eb7ee..ed01581 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
@@ -1,8 +1,10 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
import java.util.Date;
@@ -26,12 +28,24 @@
*/
private Long id;
/**
- * 检索关键字
+ * 商品名称
*/
- private String keys;
+ @TableField("sku_name")
+ private String skuName;
+ /**
+ * 商品url
+ */
+ @TableField("sku_url")
+ private String skuUrl;
+ /**
+ * 设定价格
+ */
+ @TableField("price")
+ private String price;
/**
* 最后检索时间
*/
+ @JSONField(serializeUsing = DateDeserializer.class)
@TableField("search_time")
private Date searchTime;
/**
@@ -40,12 +54,10 @@
@TableField("keep_days")
private Integer keepDays;
-
@Override
public String toString() {
return "SearchKeys{" +
"id=" + id +
- ", keys=" + keys +
", searchTime=" + searchTime +
", keepDays=" + keepDays +
"}";
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
new file mode 100644
index 0000000..f6a8a35
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
@@ -0,0 +1,30 @@
+package com.casic.missiles.modular.system.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.casic.missiles.modular.system.model.ProductInfo;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 服务类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface IProductInfoService extends IService {
+ /**
+ * 检索商品接口定义
+ * @param type jd tm
+ * @return
+ */
+ public List searchProducts(String type);
+ /**
+ * 检索商品价格信息
+ * @param type jd tm
+ * @return
+ */
+ public List searchDbProductPricePage(String type, Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java
new file mode 100644
index 0000000..e912cfd
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java
@@ -0,0 +1,218 @@
+package com.casic.missiles.modular.system.service.impl;
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.casic.missiles.modular.system.dao.ProductInfoMapper;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import lombok.SneakyThrows;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeOptions;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ *
+ * 商品信息 服务实现类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+@Service
+public class ProductInfoServiceImpl extends ServiceImpl implements IProductInfoService {
+ @Value("${casic.webdriver.path}")
+ private String path;
+ @Value("${casic.tm.account}")
+ private String account;
+ @Value("${casic.tm.pwd}")
+ private String pwd;
+ @Resource
+ private ISearchKeysService searchKeysService;
+
+ @Override
+ public List searchProducts(String type) {
+ System.setProperty("webdriver.chrome.driver", path);
+ List searchKeys = searchKeysService.list();
+ Date searchTime = new Date();
+ WebDriver webDriver = null;
+ try {
+ //驱动地址
+ ChromeOptions option = new ChromeOptions();
+ //去掉chrome 正受到自动测试软件的控制
+ option.addArguments("disable-infobars");
+ //开启开发者模式
+ option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
+ option.addArguments("--disable-blink-features");
+ option.addArguments("--disable-blink-features=AutomationControlled");
+ //初始化一个chrome浏览器实例
+ webDriver = new ChromeDriver(option);
+ //最大化窗口
+ webDriver.manage().window().maximize();
+ //设置隐性等待时间
+ webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
+ for (SearchKeys searchKey : searchKeys) {
+// List productInfos = searchJdProducts(webDriver, searchKey.getKeywords());
+// ProductInfo maxJd = productInfos.stream().max(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// ProductInfo minJd = productInfos.stream().min(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// // 过滤价格区间
+// ProductInfo info = new ProductInfo();
+// info.setKeyId(searchKey.getId());
+// info.setCreateTime(searchTime);
+// info.setMaxPrice(maxJd.getMaxPrice());
+// info.setMinPrice(minJd.getMaxPrice());
+// StringBuilder jdStr = new StringBuilder();
+// jdStr.append("京东:").append(minJd.getDescription()).append("---").append(maxJd.getDescription()).append(" ");
+// // 过滤天猫信息
+// List productTmInfos = searchTbProducts(webDriver, searchKey.getKeywords());
+// ProductInfo maxTb = productTmInfos.stream().max(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// ProductInfo minTb = productTmInfos.stream().min(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// info.setMaxTmPrice(maxTb.getMaxPrice());
+// info.setMinTmPrice(minTb.getMaxPrice());
+// jdStr.append("天猫:").append(minTb.getDescription()).append("---").append(maxTb.getDescription()).append(" ");
+
+// info.setDescription(jdStr.toString());
+// this.save(info);
+ searchKey.setSearchTime(searchTime);
+ searchKeysService.updateById(searchKey);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (webDriver != null) {
+ webDriver.close();
+ webDriver.quit();
+ }
+ }
+ return new ArrayList<>();
+ }
+
+ @Override
+ public List searchDbProductPricePage(String keywords, Page page) {
+ return this.baseMapper.searchDbProductPricePage(keywords, page);
+ }
+
+ private ProductInfo searchJdDetail(WebDriver webDriver, String url) {
+ ProductInfo productInfo = new ProductInfo();
+ //打开京东地址
+ webDriver.get(url);
+ String title = webDriver.getTitle();
+ WebElement skuEl = webDriver.findElement(By.className("sku-name"));
+ if (skuEl != null) {
+ String skuName = skuEl.getText();
+ productInfo.setDescription(skuName);
+ } else {
+ productInfo.setFlag("1");
+ }
+
+ // NO1 读取价格信息
+ WebElement priceEl = webDriver.findElement(By.className("p-price"));
+ if (priceEl != null) {
+ WebElement webP = priceEl.findElement(By.className("price"));
+ if (webP != null && NumberUtil.isNumber(webP.getText())) {
+ //设置页面价格
+ productInfo.setPrice(webP.getText());
+ } else {
+ //页面元素获取异常 判定为页面失效
+ productInfo.setFlag("1");
+ }
+ } else {
+ //页面元素获取异常 判定为页面失效
+ productInfo.setFlag("1");
+ }
+
+ // NO2 读取打折信息
+ WebElement promItem = webDriver.findElement(By.className("prom-item"));
+ if (promItem != null) {
+ //提取满减信息
+ WebElement redElm = promItem.findElement(By.className("hl_red"));
+ String text = redElm.getText();
+ if (StrUtil.isNotEmpty(text)) {
+ //提取满减
+ String bg = promItem.findElement(By.className("hl_red_bg")).getText();
+ String reg = "[\\u4E00-\\u9FA5]+";
+ List list = Stream.of(reg.split(reg)).filter(StrUtil::isNotEmpty).collect(Collectors.toList());
+ if (list.size() > 0 && list.stream().anyMatch(NumberUtil::isNumber)) {
+ //计算满减价格
+ //判断价格是否符合满减数
+ if ("满减".equals(bg) && list.size() > 2) {
+ BigDecimal skuPrice = NumberUtil.toBigDecimal(productInfo.getPrice());
+ if (skuPrice.compareTo(NumberUtil.toBigDecimal(list.get(0))) >= 0) {
+ BigDecimal discountPrice = NumberUtil.toBigDecimal(list.get(1));
+ //设置实际价格
+ productInfo.setActualPrice(skuPrice.subtract(discountPrice).toString());
+ }
+ }
+ }
+ }
+ }
+
+ return productInfo;
+ }
+
+ private List searchJdProducts(WebDriver webDriver, String keywords) {
+ //打开京东地址
+ webDriver.get("https://search.jd.com/Search?keyword=" + keywords);
+ String title = webDriver.getTitle();
+ List elementList = webDriver.findElements(By.className("gl-i-wrap"));
+ List productInfos = elementList.stream().map(webElement -> {
+ ProductInfo productInfo = new ProductInfo();
+ productInfo.setDescription(webElement.findElement(By.className("p-name")).getText());
+ String price = webElement.findElement(By.className("p-price")).getText();
+ price = price.replaceAll("¥", "");
+// productInfo.setMaxPrice(price);
+ return productInfo;
+ }).collect(Collectors.toList());
+ return productInfos;
+ }
+
+ @SneakyThrows
+ private List searchTbProducts(WebDriver webDriver, String keyWords) {
+ //打开京东地址
+ webDriver.get("https://login.taobao.com/member/login.jhtml?tpl_redirect_url=https%3A%2F%2Fwww.tmall.com&style=miniall&enup=true&newMini2=true&full_redirect=true&sub=true&from=tmall&allp=assets_css%3D3.0.10/login_pc.css&pms=1650640249767");
+ Thread.sleep(10 * 1000L);
+
+ // 预登录
+ webDriver.findElement(By.xpath("//input[@name='fm-login-id']")).sendKeys(account);
+ webDriver.findElement(By.xpath("//input[@name='fm-login-password']")).sendKeys(pwd);
+ webDriver.findElement(By.xpath("//*[@class=\"fm-button fm-submit password-login\"]")).click();
+
+ String oldHandler = webDriver.getWindowHandle();
+ webDriver.findElement(By.className("SearchInput--searchInputContent--1USWNEl")).sendKeys(keyWords);
+ Thread.sleep(10 * 1000L);
+ webDriver.findElement(By.className("SearchInput--searchButton--1Sz2UIn")).click();
+ Thread.sleep(30 * 1000L);
+ // 获取当前handler
+
+ Set sets = webDriver.getWindowHandles();
+ String newWindow = sets.stream().filter(handler -> !oldHandler.equals(handler)).findFirst().get();
+ webDriver.switchTo().window(newWindow);
+
+ List tmElementList = webDriver.findElements(By.className("product-iWrap"));
+ List productInfos = tmElementList.stream().map(pElement -> {
+ ProductInfo productInfo = new ProductInfo();
+ productInfo.setDescription(pElement.findElement(By.className("productTitle")).getText());
+ String price = pElement.findElement(By.className("productPrice")).getText();
+ System.out.println(price);
+ price = price.replaceAll("¥", "");
+// productInfo.setMaxPrice(price);
+ return productInfo;
+ }).collect(Collectors.toList());
+ return productInfos;
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductServiceImpl.java
deleted file mode 100644
index 4e72150..0000000
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductServiceImpl.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.casic.missiles.modular.system.service.impl;
-
-import com.casic.missiles.modular.system.model.ProductInfo;
-import com.casic.missiles.modular.system.service.IProductSearchService;
-import lombok.SneakyThrows;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.chrome.ChromeDriver;
-import org.openqa.selenium.chrome.ChromeOptions;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-/**
- * 产品搜索实例
- *
- * @author lwh
- */
-@Component
-public class ProductServiceImpl implements IProductSearchService {
- @Value("${casic.webdriver.path}")
- private String path;
- @Override
- public List searchProducts(String type) {
- //驱动地址
- String chromedriver = "D:\\dev-soft\\seleuim-chmod\\chromedriver.exe";
- System.setProperty("webdriver.chrome.driver", path);
- ChromeOptions option = new ChromeOptions();
- //去掉chrome 正受到自动测试软件的控制
- option.addArguments("disable-infobars");
- //开启开发者模式
- option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
- option.addArguments("--disable-blink-features");
- option.addArguments("--disable-blink-features=AutomationControlled");
- //初始化一个chrome浏览器实例
- WebDriver webDriver = new ChromeDriver(option);
- //最大化窗口
- webDriver.manage().window().maximize();
- //设置隐性等待时间
- webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
-
- return searchJdProducts(webDriver);
- }
-
- private List searchJdProducts(WebDriver webDriver) {
- //打开京东地址
- webDriver.get("https://search.jd.com/Search?keyword=%E8%8B%B9%E6%9E%9C13");
- String title = webDriver.getTitle();
- List elementList = webDriver.findElements(By.className("gl-i-wrap"));
- List productInfos = elementList.stream().map(webElement -> {
- ProductInfo productInfo = new ProductInfo();
- productInfo.setDescription(webElement.findElement(By.className("p-name")).getText());
- productInfo.setPrice(webElement.findElement(By.className("p-price")).getText());
- return productInfo;
- }).collect(Collectors.toList());
- return productInfos;
- }
-
- @SneakyThrows
- private List searchTbProducts(WebDriver webDriver) {
- //打开京东地址
- webDriver.get("https://login.taobao.com/member/login.jhtml?tpl_redirect_url=https%3A%2F%2Fwww.tmall.com&style=miniall&enup=true&newMini2=true&full_redirect=true&sub=true&from=tmall&allp=assets_css%3D3.0.10/login_pc.css&pms=1650640249767");
- Thread.sleep(10 * 1000L);
-
- // 预登录
- webDriver.findElement(By.xpath("//input[@name='fm-login-id']")).sendKeys("18600202639");
- webDriver.findElement(By.xpath("//input[@name='fm-login-password']")).sendKeys("19881126yu");
- webDriver.findElement(By.xpath("//*[@class=\"fm-button fm-submit password-login\"]")).click();
-
- String oldHandler = webDriver.getWindowHandle();
- webDriver.findElement(By.className("SearchInput--searchInputContent--1USWNEl")).sendKeys("苹果13");
- Thread.sleep(10 * 1000L);
- webDriver.findElement(By.className("SearchInput--searchButton--1Sz2UIn")).click();
- Thread.sleep(30 * 1000L);
- // 获取当前handler
-
- Set sets = webDriver.getWindowHandles();
- String newWindow = sets.stream().filter(handler -> !oldHandler.equals(handler)).findFirst().get();
- webDriver.switchTo().window(newWindow);
-
- List tmElementList = webDriver.findElements(By.className("product-iWrap"));
- List productInfos = tmElementList.stream().map(pElement -> {
- ProductInfo productInfo = new ProductInfo();
- productInfo.setDescription(pElement.findElement(By.className("productPrice")).getText());
- productInfo.setPrice(pElement.findElement(By.className("productTitle")).getText());
- return productInfo;
- }).collect(Collectors.toList());
- return productInfos;
- }
-
- public static void main(String[] args) throws InterruptedException {
- //驱动地址
- String chromedriver = "D:\\dev-soft\\seleuim-chmod\\chromedriver.exe";
- System.setProperty("webdriver.chrome.driver", chromedriver);
- ChromeOptions option = new ChromeOptions();
- //去掉chrome 正受到自动测试软件的控制
- option.addArguments("disable-infobars");
- //开启开发者模式
- option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
- option.addArguments("--disable-blink-features");
- option.addArguments("--disable-blink-features=AutomationControlled");
- //初始化一个chrome浏览器实例
- WebDriver webDriver = new ChromeDriver(option);
- //最大化窗口
- webDriver.manage().window().maximize();
- //设置隐性等待时间
- webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
- //打开京东地址
- webDriver.get("https://login.taobao.com/member/login.jhtml?tpl_redirect_url=https%3A%2F%2Fwww.tmall.com&style=miniall&enup=true&newMini2=true&full_redirect=true&sub=true&from=tmall&allp=assets_css%3D3.0.10/login_pc.css&pms=1650640249767");
- Thread.sleep(10 * 1000L);
-
- // 预登录
- webDriver.findElement(By.xpath("//input[@name='fm-login-id']")).sendKeys("18600202639");
- webDriver.findElement(By.xpath("//input[@name='fm-login-password']")).sendKeys("19881126yu");
- webDriver.findElement(By.xpath("//*[@class=\"fm-button fm-submit password-login\"]")).click();
-
- String oldHandler = webDriver.getWindowHandle();
- webDriver.findElement(By.className("SearchInput--searchInputContent--1USWNEl")).sendKeys("苹果13");
- Thread.sleep(10 * 1000L);
- webDriver.findElement(By.className("SearchInput--searchButton--1Sz2UIn")).click();
- Thread.sleep(30 * 1000L);
- // 获取当前handler
-
- Set sets = webDriver.getWindowHandles();
- String newWindow = sets.stream().filter(handler -> !oldHandler.equals(handler)).findFirst().get();
- webDriver.switchTo().window(newWindow);
-
- List tmElementList = webDriver.findElements(By.className("product-iWrap"));
- List productInfos = tmElementList.stream().map(pElement -> {
- ProductInfo productInfo = new ProductInfo();
- productInfo.setDescription(pElement.findElement(By.className("productPrice")).getText());
- productInfo.setPrice(pElement.findElement(By.className("productTitle")).getText());
- return productInfo;
- }).collect(Collectors.toList());
-
- System.out.println(productInfos);
- }
-}
diff --git a/casic-web/pom.xml b/casic-web/pom.xml
index 35f0017..eb21475 100644
--- a/casic-web/pom.xml
+++ b/casic-web/pom.xml
@@ -78,11 +78,6 @@
casic-admin-support
${admin.version}
-
- com.casic
- casic-job-starter
- ${extension.version}
-
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
index 348f2a0..4f41b58 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
@@ -5,14 +5,14 @@
-
+
- id, keys, search_time AS searchTime, keep_days AS keepDays
+ id, keywords, search_time AS searchTime, keep_days AS keepDays
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
new file mode 100644
index 0000000..df0766c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
@@ -0,0 +1,38 @@
+package com.casic.missiles.modular.system.job;
+
+import cn.hutool.core.util.RandomUtil;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import lombok.SneakyThrows;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+
+/**
+ * @ClassName QuartzJob
+ * @Description 依赖casic-job-quartz,并在CasicApplication上增加注解 @EnableScheduling
+ * @Author lwh
+ * @Date 2021/2/5 11:20
+ * @Version 1.0
+ */
+@Component
+public class QuartzJob {
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ *
+ */
+ @SneakyThrows
+ @Scheduled(cron = "0 0 10,14,16 * * ?")
+ public void execute() {
+ try {
+ Thread.sleep(RandomUtil.randomBigDecimal(new BigDecimal(2000)).intValue());
+ System.out.println("-----Thread ID 每60秒执行一次");
+ productInfoService.searchProducts(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
index 03190bf..d5c4ecd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
@@ -1,14 +1,74 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
+import java.util.Date;
+
/**
- * 产品信息
+ *
+ * 商品信息
+ *
*
- * @author lenovo
+ * @author stylefeng123
+ * @since 2022-05-05
*/
@Data
-public class ProductInfo {
- private String description;
+@TableName("reptile_product_info")
+public class ProductInfo extends Model {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ private Long id;
+ /**
+ * 页面价格
+ */
+ @TableField("price")
private String price;
+ /**
+ * 满减价格
+ */
+ @TableField("actual_price")
+ private String actualPrice;
+ /**
+ * 优惠信息
+ */
+ @TableField("discount")
+ private String discount;
+
+ /**
+ * 其他信息
+ */
+ private String description;
+
+
+ @TableField("key_id")
+ private Long keyId;
+
+ /**
+ * 0 页面无效 1 价格偏高
+ */
+ private String flag;
+ @JSONField(serializeUsing = DateDeserializer.class)
+ @TableField("create_time")
+ private Date createTime;
+ @TableField(exist = false)
+ private String skuName;
+ @TableField(exist = false)
+ private String skuUrl;
+
+ @Override
+ public String toString() {
+ return "ProductInfo{" +
+ "id=" + id +
+ ", description=" + description +
+ "}";
+ }
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
index 09eb7ee..ed01581 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
@@ -1,8 +1,10 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
import java.util.Date;
@@ -26,12 +28,24 @@
*/
private Long id;
/**
- * 检索关键字
+ * 商品名称
*/
- private String keys;
+ @TableField("sku_name")
+ private String skuName;
+ /**
+ * 商品url
+ */
+ @TableField("sku_url")
+ private String skuUrl;
+ /**
+ * 设定价格
+ */
+ @TableField("price")
+ private String price;
/**
* 最后检索时间
*/
+ @JSONField(serializeUsing = DateDeserializer.class)
@TableField("search_time")
private Date searchTime;
/**
@@ -40,12 +54,10 @@
@TableField("keep_days")
private Integer keepDays;
-
@Override
public String toString() {
return "SearchKeys{" +
"id=" + id +
- ", keys=" + keys +
", searchTime=" + searchTime +
", keepDays=" + keepDays +
"}";
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
new file mode 100644
index 0000000..f6a8a35
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
@@ -0,0 +1,30 @@
+package com.casic.missiles.modular.system.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.casic.missiles.modular.system.model.ProductInfo;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 服务类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface IProductInfoService extends IService {
+ /**
+ * 检索商品接口定义
+ * @param type jd tm
+ * @return
+ */
+ public List searchProducts(String type);
+ /**
+ * 检索商品价格信息
+ * @param type jd tm
+ * @return
+ */
+ public List searchDbProductPricePage(String type, Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java
new file mode 100644
index 0000000..e912cfd
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java
@@ -0,0 +1,218 @@
+package com.casic.missiles.modular.system.service.impl;
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.casic.missiles.modular.system.dao.ProductInfoMapper;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import lombok.SneakyThrows;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeOptions;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ *
+ * 商品信息 服务实现类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+@Service
+public class ProductInfoServiceImpl extends ServiceImpl implements IProductInfoService {
+ @Value("${casic.webdriver.path}")
+ private String path;
+ @Value("${casic.tm.account}")
+ private String account;
+ @Value("${casic.tm.pwd}")
+ private String pwd;
+ @Resource
+ private ISearchKeysService searchKeysService;
+
+ @Override
+ public List searchProducts(String type) {
+ System.setProperty("webdriver.chrome.driver", path);
+ List searchKeys = searchKeysService.list();
+ Date searchTime = new Date();
+ WebDriver webDriver = null;
+ try {
+ //驱动地址
+ ChromeOptions option = new ChromeOptions();
+ //去掉chrome 正受到自动测试软件的控制
+ option.addArguments("disable-infobars");
+ //开启开发者模式
+ option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
+ option.addArguments("--disable-blink-features");
+ option.addArguments("--disable-blink-features=AutomationControlled");
+ //初始化一个chrome浏览器实例
+ webDriver = new ChromeDriver(option);
+ //最大化窗口
+ webDriver.manage().window().maximize();
+ //设置隐性等待时间
+ webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
+ for (SearchKeys searchKey : searchKeys) {
+// List productInfos = searchJdProducts(webDriver, searchKey.getKeywords());
+// ProductInfo maxJd = productInfos.stream().max(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// ProductInfo minJd = productInfos.stream().min(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// // 过滤价格区间
+// ProductInfo info = new ProductInfo();
+// info.setKeyId(searchKey.getId());
+// info.setCreateTime(searchTime);
+// info.setMaxPrice(maxJd.getMaxPrice());
+// info.setMinPrice(minJd.getMaxPrice());
+// StringBuilder jdStr = new StringBuilder();
+// jdStr.append("京东:").append(minJd.getDescription()).append("---").append(maxJd.getDescription()).append(" ");
+// // 过滤天猫信息
+// List productTmInfos = searchTbProducts(webDriver, searchKey.getKeywords());
+// ProductInfo maxTb = productTmInfos.stream().max(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// ProductInfo minTb = productTmInfos.stream().min(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// info.setMaxTmPrice(maxTb.getMaxPrice());
+// info.setMinTmPrice(minTb.getMaxPrice());
+// jdStr.append("天猫:").append(minTb.getDescription()).append("---").append(maxTb.getDescription()).append(" ");
+
+// info.setDescription(jdStr.toString());
+// this.save(info);
+ searchKey.setSearchTime(searchTime);
+ searchKeysService.updateById(searchKey);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (webDriver != null) {
+ webDriver.close();
+ webDriver.quit();
+ }
+ }
+ return new ArrayList<>();
+ }
+
+ @Override
+ public List searchDbProductPricePage(String keywords, Page page) {
+ return this.baseMapper.searchDbProductPricePage(keywords, page);
+ }
+
+ private ProductInfo searchJdDetail(WebDriver webDriver, String url) {
+ ProductInfo productInfo = new ProductInfo();
+ //打开京东地址
+ webDriver.get(url);
+ String title = webDriver.getTitle();
+ WebElement skuEl = webDriver.findElement(By.className("sku-name"));
+ if (skuEl != null) {
+ String skuName = skuEl.getText();
+ productInfo.setDescription(skuName);
+ } else {
+ productInfo.setFlag("1");
+ }
+
+ // NO1 读取价格信息
+ WebElement priceEl = webDriver.findElement(By.className("p-price"));
+ if (priceEl != null) {
+ WebElement webP = priceEl.findElement(By.className("price"));
+ if (webP != null && NumberUtil.isNumber(webP.getText())) {
+ //设置页面价格
+ productInfo.setPrice(webP.getText());
+ } else {
+ //页面元素获取异常 判定为页面失效
+ productInfo.setFlag("1");
+ }
+ } else {
+ //页面元素获取异常 判定为页面失效
+ productInfo.setFlag("1");
+ }
+
+ // NO2 读取打折信息
+ WebElement promItem = webDriver.findElement(By.className("prom-item"));
+ if (promItem != null) {
+ //提取满减信息
+ WebElement redElm = promItem.findElement(By.className("hl_red"));
+ String text = redElm.getText();
+ if (StrUtil.isNotEmpty(text)) {
+ //提取满减
+ String bg = promItem.findElement(By.className("hl_red_bg")).getText();
+ String reg = "[\\u4E00-\\u9FA5]+";
+ List list = Stream.of(reg.split(reg)).filter(StrUtil::isNotEmpty).collect(Collectors.toList());
+ if (list.size() > 0 && list.stream().anyMatch(NumberUtil::isNumber)) {
+ //计算满减价格
+ //判断价格是否符合满减数
+ if ("满减".equals(bg) && list.size() > 2) {
+ BigDecimal skuPrice = NumberUtil.toBigDecimal(productInfo.getPrice());
+ if (skuPrice.compareTo(NumberUtil.toBigDecimal(list.get(0))) >= 0) {
+ BigDecimal discountPrice = NumberUtil.toBigDecimal(list.get(1));
+ //设置实际价格
+ productInfo.setActualPrice(skuPrice.subtract(discountPrice).toString());
+ }
+ }
+ }
+ }
+ }
+
+ return productInfo;
+ }
+
+ private List searchJdProducts(WebDriver webDriver, String keywords) {
+ //打开京东地址
+ webDriver.get("https://search.jd.com/Search?keyword=" + keywords);
+ String title = webDriver.getTitle();
+ List elementList = webDriver.findElements(By.className("gl-i-wrap"));
+ List productInfos = elementList.stream().map(webElement -> {
+ ProductInfo productInfo = new ProductInfo();
+ productInfo.setDescription(webElement.findElement(By.className("p-name")).getText());
+ String price = webElement.findElement(By.className("p-price")).getText();
+ price = price.replaceAll("¥", "");
+// productInfo.setMaxPrice(price);
+ return productInfo;
+ }).collect(Collectors.toList());
+ return productInfos;
+ }
+
+ @SneakyThrows
+ private List searchTbProducts(WebDriver webDriver, String keyWords) {
+ //打开京东地址
+ webDriver.get("https://login.taobao.com/member/login.jhtml?tpl_redirect_url=https%3A%2F%2Fwww.tmall.com&style=miniall&enup=true&newMini2=true&full_redirect=true&sub=true&from=tmall&allp=assets_css%3D3.0.10/login_pc.css&pms=1650640249767");
+ Thread.sleep(10 * 1000L);
+
+ // 预登录
+ webDriver.findElement(By.xpath("//input[@name='fm-login-id']")).sendKeys(account);
+ webDriver.findElement(By.xpath("//input[@name='fm-login-password']")).sendKeys(pwd);
+ webDriver.findElement(By.xpath("//*[@class=\"fm-button fm-submit password-login\"]")).click();
+
+ String oldHandler = webDriver.getWindowHandle();
+ webDriver.findElement(By.className("SearchInput--searchInputContent--1USWNEl")).sendKeys(keyWords);
+ Thread.sleep(10 * 1000L);
+ webDriver.findElement(By.className("SearchInput--searchButton--1Sz2UIn")).click();
+ Thread.sleep(30 * 1000L);
+ // 获取当前handler
+
+ Set sets = webDriver.getWindowHandles();
+ String newWindow = sets.stream().filter(handler -> !oldHandler.equals(handler)).findFirst().get();
+ webDriver.switchTo().window(newWindow);
+
+ List tmElementList = webDriver.findElements(By.className("product-iWrap"));
+ List productInfos = tmElementList.stream().map(pElement -> {
+ ProductInfo productInfo = new ProductInfo();
+ productInfo.setDescription(pElement.findElement(By.className("productTitle")).getText());
+ String price = pElement.findElement(By.className("productPrice")).getText();
+ System.out.println(price);
+ price = price.replaceAll("¥", "");
+// productInfo.setMaxPrice(price);
+ return productInfo;
+ }).collect(Collectors.toList());
+ return productInfos;
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductServiceImpl.java
deleted file mode 100644
index 4e72150..0000000
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductServiceImpl.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.casic.missiles.modular.system.service.impl;
-
-import com.casic.missiles.modular.system.model.ProductInfo;
-import com.casic.missiles.modular.system.service.IProductSearchService;
-import lombok.SneakyThrows;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.chrome.ChromeDriver;
-import org.openqa.selenium.chrome.ChromeOptions;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-/**
- * 产品搜索实例
- *
- * @author lwh
- */
-@Component
-public class ProductServiceImpl implements IProductSearchService {
- @Value("${casic.webdriver.path}")
- private String path;
- @Override
- public List searchProducts(String type) {
- //驱动地址
- String chromedriver = "D:\\dev-soft\\seleuim-chmod\\chromedriver.exe";
- System.setProperty("webdriver.chrome.driver", path);
- ChromeOptions option = new ChromeOptions();
- //去掉chrome 正受到自动测试软件的控制
- option.addArguments("disable-infobars");
- //开启开发者模式
- option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
- option.addArguments("--disable-blink-features");
- option.addArguments("--disable-blink-features=AutomationControlled");
- //初始化一个chrome浏览器实例
- WebDriver webDriver = new ChromeDriver(option);
- //最大化窗口
- webDriver.manage().window().maximize();
- //设置隐性等待时间
- webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
-
- return searchJdProducts(webDriver);
- }
-
- private List searchJdProducts(WebDriver webDriver) {
- //打开京东地址
- webDriver.get("https://search.jd.com/Search?keyword=%E8%8B%B9%E6%9E%9C13");
- String title = webDriver.getTitle();
- List elementList = webDriver.findElements(By.className("gl-i-wrap"));
- List productInfos = elementList.stream().map(webElement -> {
- ProductInfo productInfo = new ProductInfo();
- productInfo.setDescription(webElement.findElement(By.className("p-name")).getText());
- productInfo.setPrice(webElement.findElement(By.className("p-price")).getText());
- return productInfo;
- }).collect(Collectors.toList());
- return productInfos;
- }
-
- @SneakyThrows
- private List searchTbProducts(WebDriver webDriver) {
- //打开京东地址
- webDriver.get("https://login.taobao.com/member/login.jhtml?tpl_redirect_url=https%3A%2F%2Fwww.tmall.com&style=miniall&enup=true&newMini2=true&full_redirect=true&sub=true&from=tmall&allp=assets_css%3D3.0.10/login_pc.css&pms=1650640249767");
- Thread.sleep(10 * 1000L);
-
- // 预登录
- webDriver.findElement(By.xpath("//input[@name='fm-login-id']")).sendKeys("18600202639");
- webDriver.findElement(By.xpath("//input[@name='fm-login-password']")).sendKeys("19881126yu");
- webDriver.findElement(By.xpath("//*[@class=\"fm-button fm-submit password-login\"]")).click();
-
- String oldHandler = webDriver.getWindowHandle();
- webDriver.findElement(By.className("SearchInput--searchInputContent--1USWNEl")).sendKeys("苹果13");
- Thread.sleep(10 * 1000L);
- webDriver.findElement(By.className("SearchInput--searchButton--1Sz2UIn")).click();
- Thread.sleep(30 * 1000L);
- // 获取当前handler
-
- Set sets = webDriver.getWindowHandles();
- String newWindow = sets.stream().filter(handler -> !oldHandler.equals(handler)).findFirst().get();
- webDriver.switchTo().window(newWindow);
-
- List tmElementList = webDriver.findElements(By.className("product-iWrap"));
- List productInfos = tmElementList.stream().map(pElement -> {
- ProductInfo productInfo = new ProductInfo();
- productInfo.setDescription(pElement.findElement(By.className("productPrice")).getText());
- productInfo.setPrice(pElement.findElement(By.className("productTitle")).getText());
- return productInfo;
- }).collect(Collectors.toList());
- return productInfos;
- }
-
- public static void main(String[] args) throws InterruptedException {
- //驱动地址
- String chromedriver = "D:\\dev-soft\\seleuim-chmod\\chromedriver.exe";
- System.setProperty("webdriver.chrome.driver", chromedriver);
- ChromeOptions option = new ChromeOptions();
- //去掉chrome 正受到自动测试软件的控制
- option.addArguments("disable-infobars");
- //开启开发者模式
- option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
- option.addArguments("--disable-blink-features");
- option.addArguments("--disable-blink-features=AutomationControlled");
- //初始化一个chrome浏览器实例
- WebDriver webDriver = new ChromeDriver(option);
- //最大化窗口
- webDriver.manage().window().maximize();
- //设置隐性等待时间
- webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
- //打开京东地址
- webDriver.get("https://login.taobao.com/member/login.jhtml?tpl_redirect_url=https%3A%2F%2Fwww.tmall.com&style=miniall&enup=true&newMini2=true&full_redirect=true&sub=true&from=tmall&allp=assets_css%3D3.0.10/login_pc.css&pms=1650640249767");
- Thread.sleep(10 * 1000L);
-
- // 预登录
- webDriver.findElement(By.xpath("//input[@name='fm-login-id']")).sendKeys("18600202639");
- webDriver.findElement(By.xpath("//input[@name='fm-login-password']")).sendKeys("19881126yu");
- webDriver.findElement(By.xpath("//*[@class=\"fm-button fm-submit password-login\"]")).click();
-
- String oldHandler = webDriver.getWindowHandle();
- webDriver.findElement(By.className("SearchInput--searchInputContent--1USWNEl")).sendKeys("苹果13");
- Thread.sleep(10 * 1000L);
- webDriver.findElement(By.className("SearchInput--searchButton--1Sz2UIn")).click();
- Thread.sleep(30 * 1000L);
- // 获取当前handler
-
- Set sets = webDriver.getWindowHandles();
- String newWindow = sets.stream().filter(handler -> !oldHandler.equals(handler)).findFirst().get();
- webDriver.switchTo().window(newWindow);
-
- List tmElementList = webDriver.findElements(By.className("product-iWrap"));
- List productInfos = tmElementList.stream().map(pElement -> {
- ProductInfo productInfo = new ProductInfo();
- productInfo.setDescription(pElement.findElement(By.className("productPrice")).getText());
- productInfo.setPrice(pElement.findElement(By.className("productTitle")).getText());
- return productInfo;
- }).collect(Collectors.toList());
-
- System.out.println(productInfos);
- }
-}
diff --git a/casic-web/pom.xml b/casic-web/pom.xml
index 35f0017..eb21475 100644
--- a/casic-web/pom.xml
+++ b/casic-web/pom.xml
@@ -78,11 +78,6 @@
casic-admin-support
${admin.version}
-
- com.casic
- casic-job-starter
- ${extension.version}
-
diff --git a/casic-web/src/main/java/com/casic/missiles/ZkTest.java b/casic-web/src/main/java/com/casic/missiles/ZkTest.java
deleted file mode 100644
index 7e5df40..0000000
--- a/casic-web/src/main/java/com/casic/missiles/ZkTest.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.casic.missiles;
-
-import com.casic.missiles.core.util.ZkUtil;
-import org.apache.zookeeper.ZooDefs;
-
-public class ZkTest {
- /**
- * 白名单 IP添加(待增项)
- *
- * @param args
- * @throws Exception
- */
- public static void main(String[] args) throws Exception {
- String zkPath = "/ss-job";
- String connectString = "localhost:2181";
- int perms = ZooDefs.Perms.ALL;
- String scheme = "digest";
- String auth = "admin:Casic203";
- ZkUtil.addDigests(scheme,perms, null, connectString, zkPath);
-// ZkUtil.deletePath(scheme, connectString, zkPath, auth, null);
- }
-}
diff --git a/casic-server/pom.xml b/casic-server/pom.xml
index 0e47785..0adbba2 100644
--- a/casic-server/pom.xml
+++ b/casic-server/pom.xml
@@ -37,9 +37,19 @@
com.casic
+ casic-job-quartz
+ ${extension.version}
+
+
+ com.casic
casic-selenium-core
${extension.version}
+
+ com.google.guava
+ guava
+ 30.1-jre
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
new file mode 100644
index 0000000..9dc3950
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/ProductInfoController.java
@@ -0,0 +1,94 @@
+package com.casic.missiles.modular.system.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.core.base.controller.BaseController;
+import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.response.ResponseData;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 商品信息管理控制器
+ *
+ * @author dev
+ * @Date 2022-05-05 15:46:28
+ */
+@Controller
+@RequestMapping("/productInfo")
+public class ProductInfoController extends BaseController {
+ @Resource
+ private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ * 获取商品信息管理列表
+ */
+ @RequestMapping(value = "/list")
+ @ResponseBody
+ public Object list(String condition) {
+ return productInfoService.list(null);
+ }
+
+ /**
+ * 获取商品信息管理分页列表
+ */
+ @RequestMapping(value = "/listPage")
+ @ResponseBody
+ public Object listPage(String condition) {
+ Page page = PageFactory.defaultPage();
+ QueryWrapper query = new QueryWrapper<>();
+ List productInfos = productInfoService.searchDbProductPricePage(condition, page);
+ page.setRecords(productInfos);
+ return ResponseData.success(super.packForBT(page));
+ }
+
+ /**
+ * 新增商品信息管理
+ */
+ @RequestMapping(value = "/add")
+ @ResponseBody
+ public Object add(ProductInfo productInfo) {
+ productInfoService.save(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 删除商品信息管理
+ */
+ @RequestMapping(value = "/delete")
+ @ResponseBody
+ public Object delete(@RequestParam String productInfoId) {
+ productInfoService.removeById(productInfoId);
+ return ResponseData.success();
+ }
+
+ /**
+ * 修改商品信息管理
+ */
+ @RequestMapping(value = "/update")
+ @ResponseBody
+ public Object update(ProductInfo productInfo) {
+ productInfoService.updateById(productInfo);
+ return ResponseData.success();
+ }
+
+ /**
+ * 商品信息管理详情
+ */
+ @RequestMapping(value = "/detail/{productInfoId}")
+ @ResponseBody
+ public Object detail(@PathVariable("productInfoId") String productInfoId) {
+ return ResponseData.success(productInfoService.getById(productInfoId));
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
index 78c1892..446be24 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/controller/SearchKeysController.java
@@ -1,11 +1,14 @@
package com.casic.missiles.modular.system.controller;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.BaseController;
import com.casic.missiles.core.page.PageFactory;
+import com.casic.missiles.model.form.IdForms;
import com.casic.missiles.model.response.ResponseData;
import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
import com.casic.missiles.modular.system.service.ISearchKeysService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@@ -24,7 +27,25 @@
@Resource
private ISearchKeysService searchKeysService;
+ @Resource
+ private IProductInfoService productInfoService;
+ /**
+ * 获取关键字管理列表
+ */
+ @GetMapping(value = "/loadSearch")
+ @ResponseBody
+ public Object loadSearch(String condition) {
+ new Thread(){
+ @Override
+ public void run() {
+ super.run();
+ productInfoService.searchProducts(null);
+ }
+ }.start();
+
+ return ResponseData.success();
+ }
/**
* 获取关键字管理列表
@@ -43,6 +64,10 @@
public Object listPage(String condition) {
Page page = PageFactory.defaultPage();
QueryWrapper query = new QueryWrapper<>();
+ if (StrUtil.isNotEmpty(condition)) {
+ query.like("keywords", condition);
+ }
+
page = searchKeysService.page(page, query);
return ResponseData.success(super.packForBT(page));
}
@@ -52,7 +77,7 @@
*/
@PostMapping(value = "/add")
@ResponseBody
- public Object add(SearchKeys searchKeys) {
+ public Object add(@RequestBody SearchKeys searchKeys) {
searchKeysService.save(searchKeys);
return ResponseData.success();
}
@@ -62,8 +87,8 @@
*/
@PostMapping(value = "/delete")
@ResponseBody
- public Object delete(@RequestParam String searchKeysId) {
- searchKeysService.removeById(searchKeysId);
+ public Object delete(@RequestBody IdForms searchKeysIds) {
+ searchKeysService.removeByIds(searchKeysIds.getIds());
return ResponseData.success();
}
@@ -73,7 +98,7 @@
*/
@PostMapping(value = "/update")
@ResponseBody
- public Object update(SearchKeys searchKeys) {
+ public Object update(@RequestBody SearchKeys searchKeys) {
searchKeysService.updateById(searchKeys);
return ResponseData.success();
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
new file mode 100644
index 0000000..c3d1185
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/ProductInfoMapper.java
@@ -0,0 +1,26 @@
+package com.casic.missiles.modular.system.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 Mapper 接口
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface ProductInfoMapper extends BaseMapper {
+
+ /**
+ * 产品数据检索
+ *
+ * @return 产品价格列表
+ */
+ List searchDbProductPricePage(@Param("keywords") String keywords, @Param("page") Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
new file mode 100644
index 0000000..99c83ba
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/ProductInfoMapper.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id, max_price AS maxPrice, min_price AS minPrice, description
+
+
+
+ '%' || #{keywords}|| '%'
+
+
+ CONCAT('%',#{keywords},'%')
+
+
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
index 348f2a0..4f41b58 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/dao/mapping/SearchKeysMapper.xml
@@ -5,14 +5,14 @@
-
+
- id, keys, search_time AS searchTime, keep_days AS keepDays
+ id, keywords, search_time AS searchTime, keep_days AS keepDays
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
new file mode 100644
index 0000000..df0766c
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/job/QuartzJob.java
@@ -0,0 +1,38 @@
+package com.casic.missiles.modular.system.job;
+
+import cn.hutool.core.util.RandomUtil;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import lombok.SneakyThrows;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+
+/**
+ * @ClassName QuartzJob
+ * @Description 依赖casic-job-quartz,并在CasicApplication上增加注解 @EnableScheduling
+ * @Author lwh
+ * @Date 2021/2/5 11:20
+ * @Version 1.0
+ */
+@Component
+public class QuartzJob {
+ @Resource
+ private IProductInfoService productInfoService;
+
+ /**
+ *
+ */
+ @SneakyThrows
+ @Scheduled(cron = "0 0 10,14,16 * * ?")
+ public void execute() {
+ try {
+ Thread.sleep(RandomUtil.randomBigDecimal(new BigDecimal(2000)).intValue());
+ System.out.println("-----Thread ID 每60秒执行一次");
+ productInfoService.searchProducts(null);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
index 03190bf..d5c4ecd 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/ProductInfo.java
@@ -1,14 +1,74 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
+import java.util.Date;
+
/**
- * 产品信息
+ *
+ * 商品信息
+ *
*
- * @author lenovo
+ * @author stylefeng123
+ * @since 2022-05-05
*/
@Data
-public class ProductInfo {
- private String description;
+@TableName("reptile_product_info")
+public class ProductInfo extends Model {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 主键
+ */
+ private Long id;
+ /**
+ * 页面价格
+ */
+ @TableField("price")
private String price;
+ /**
+ * 满减价格
+ */
+ @TableField("actual_price")
+ private String actualPrice;
+ /**
+ * 优惠信息
+ */
+ @TableField("discount")
+ private String discount;
+
+ /**
+ * 其他信息
+ */
+ private String description;
+
+
+ @TableField("key_id")
+ private Long keyId;
+
+ /**
+ * 0 页面无效 1 价格偏高
+ */
+ private String flag;
+ @JSONField(serializeUsing = DateDeserializer.class)
+ @TableField("create_time")
+ private Date createTime;
+ @TableField(exist = false)
+ private String skuName;
+ @TableField(exist = false)
+ private String skuUrl;
+
+ @Override
+ public String toString() {
+ return "ProductInfo{" +
+ "id=" + id +
+ ", description=" + description +
+ "}";
+ }
}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
index 09eb7ee..ed01581 100644
--- a/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/model/SearchKeys.java
@@ -1,8 +1,10 @@
package com.casic.missiles.modular.system.model;
+import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.casic.missiles.core.base.json.DateDeserializer;
import lombok.Data;
import java.util.Date;
@@ -26,12 +28,24 @@
*/
private Long id;
/**
- * 检索关键字
+ * 商品名称
*/
- private String keys;
+ @TableField("sku_name")
+ private String skuName;
+ /**
+ * 商品url
+ */
+ @TableField("sku_url")
+ private String skuUrl;
+ /**
+ * 设定价格
+ */
+ @TableField("price")
+ private String price;
/**
* 最后检索时间
*/
+ @JSONField(serializeUsing = DateDeserializer.class)
@TableField("search_time")
private Date searchTime;
/**
@@ -40,12 +54,10 @@
@TableField("keep_days")
private Integer keepDays;
-
@Override
public String toString() {
return "SearchKeys{" +
"id=" + id +
- ", keys=" + keys +
", searchTime=" + searchTime +
", keepDays=" + keepDays +
"}";
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
new file mode 100644
index 0000000..f6a8a35
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/IProductInfoService.java
@@ -0,0 +1,30 @@
+package com.casic.missiles.modular.system.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.casic.missiles.modular.system.model.ProductInfo;
+
+import java.util.List;
+
+/**
+ *
+ * 商品信息 服务类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+public interface IProductInfoService extends IService {
+ /**
+ * 检索商品接口定义
+ * @param type jd tm
+ * @return
+ */
+ public List searchProducts(String type);
+ /**
+ * 检索商品价格信息
+ * @param type jd tm
+ * @return
+ */
+ public List searchDbProductPricePage(String type, Page page);
+}
diff --git a/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java
new file mode 100644
index 0000000..e912cfd
--- /dev/null
+++ b/casic-server/src/main/java/com/casic/missiles/modular/system/service/impl/ProductInfoServiceImpl.java
@@ -0,0 +1,218 @@
+package com.casic.missiles.modular.system.service.impl;
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.casic.missiles.modular.system.dao.ProductInfoMapper;
+import com.casic.missiles.modular.system.model.ProductInfo;
+import com.casic.missiles.modular.system.model.SearchKeys;
+import com.casic.missiles.modular.system.service.IProductInfoService;
+import com.casic.missiles.modular.system.service.ISearchKeysService;
+import lombok.SneakyThrows;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeOptions;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ *
+ * 商品信息 服务实现类
+ *
+ *
+ * @author stylefeng123
+ * @since 2022-05-05
+ */
+@Service
+public class ProductInfoServiceImpl extends ServiceImpl implements IProductInfoService {
+ @Value("${casic.webdriver.path}")
+ private String path;
+ @Value("${casic.tm.account}")
+ private String account;
+ @Value("${casic.tm.pwd}")
+ private String pwd;
+ @Resource
+ private ISearchKeysService searchKeysService;
+
+ @Override
+ public List searchProducts(String type) {
+ System.setProperty("webdriver.chrome.driver", path);
+ List searchKeys = searchKeysService.list();
+ Date searchTime = new Date();
+ WebDriver webDriver = null;
+ try {
+ //驱动地址
+ ChromeOptions option = new ChromeOptions();
+ //去掉chrome 正受到自动测试软件的控制
+ option.addArguments("disable-infobars");
+ //开启开发者模式
+ option.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
+ option.addArguments("--disable-blink-features");
+ option.addArguments("--disable-blink-features=AutomationControlled");
+ //初始化一个chrome浏览器实例
+ webDriver = new ChromeDriver(option);
+ //最大化窗口
+ webDriver.manage().window().maximize();
+ //设置隐性等待时间
+ webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
+ for (SearchKeys searchKey : searchKeys) {
+// List productInfos = searchJdProducts(webDriver, searchKey.getKeywords());
+// ProductInfo maxJd = productInfos.stream().max(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// ProductInfo minJd = productInfos.stream().min(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// // 过滤价格区间
+// ProductInfo info = new ProductInfo();
+// info.setKeyId(searchKey.getId());
+// info.setCreateTime(searchTime);
+// info.setMaxPrice(maxJd.getMaxPrice());
+// info.setMinPrice(minJd.getMaxPrice());
+// StringBuilder jdStr = new StringBuilder();
+// jdStr.append("京东:").append(minJd.getDescription()).append("---").append(maxJd.getDescription()).append(" ");
+// // 过滤天猫信息
+// List productTmInfos = searchTbProducts(webDriver, searchKey.getKeywords());
+// ProductInfo maxTb = productTmInfos.stream().max(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// ProductInfo minTb = productTmInfos.stream().min(Comparator.comparing(ProductInfo::getMaxPrice)).get();
+// info.setMaxTmPrice(maxTb.getMaxPrice());
+// info.setMinTmPrice(minTb.getMaxPrice());
+// jdStr.append("天猫:").append(minTb.getDescription()).append("---").append(maxTb.getDescription()).append(" ");
+
+// info.setDescription(jdStr.toString());
+// this.save(info);
+ searchKey.setSearchTime(searchTime);
+ searchKeysService.updateById(searchKey);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (webDriver != null) {
+ webDriver.close();
+ webDriver.quit();
+ }
+ }
+ return new ArrayList<>();
+ }
+
+ @Override
+ public List searchDbProductPricePage(String keywords, Page page) {
+ return this.baseMapper.searchDbProductPricePage(keywords, page);
+ }
+
+ private ProductInfo searchJdDetail(WebDriver webDriver, String url) {
+ ProductInfo productInfo = new ProductInfo();
+ //打开京东地址
+ webDriver.get(url);
+ String title = webDriver.getTitle();
+ WebElement skuEl = webDriver.findElement(By.className("sku-name"));
+ if (skuEl != null) {
+ String skuName = skuEl.getText();
+ productInfo.setDescription(skuName);
+ } else {
+ productInfo.setFlag("1");
+ }
+
+ // NO1 读取价格信息
+ WebElement priceEl = webDriver.findElement(By.className("p-price"));
+ if (priceEl != null) {
+ WebElement webP = priceEl.findElement(By.className("price"));
+ if (webP != null && NumberUtil.isNumber(webP.getText())) {
+ //设置页面价格
+ productInfo.setPrice(webP.getText());
+ } else {
+ //页面元素获取异常 判定为页面失效
+ productInfo.setFlag("1");
+ }
+ } else {
+ //页面元素获取异常 判定为页面失效
+ productInfo.setFlag("1");
+ }
+
+ // NO2 读取打折信息
+ WebElement promItem = webDriver.findElement(By.className("prom-item"));
+ if (promItem != null) {
+ //提取满减信息
+ WebElement redElm = promItem.findElement(By.className("hl_red"));
+ String text = redElm.getText();
+ if (StrUtil.isNotEmpty(text)) {
+ //提取满减
+ String bg = promItem.findElement(By.className("hl_red_bg")).getText();
+ String reg = "[\\u4E00-\\u9FA5]+";
+ List list = Stream.of(reg.split(reg)).filter(StrUtil::isNotEmpty).collect(Collectors.toList());
+ if (list.size() > 0 && list.stream().anyMatch(NumberUtil::isNumber)) {
+ //计算满减价格
+ //判断价格是否符合满减数
+ if ("满减".equals(bg) && list.size() > 2) {
+ BigDecimal skuPrice = NumberUtil.toBigDecimal(productInfo.getPrice());
+ if (skuPrice.compareTo(NumberUtil.toBigDecimal(list.get(0))) >= 0) {
+ BigDecimal discountPrice = NumberUtil.toBigDecimal(list.get(1));
+ //设置实际价格
+ productInfo.setActualPrice(skuPrice.subtract(discountPrice).toString());
+ }
+ }
+ }
+ }
+ }
+
+ return productInfo;
+ }
+
+ private List searchJdProducts(WebDriver webDriver, String keywords) {
+ //打开京东地址
+ webDriver.get("https://search.jd.com/Search?keyword=" + keywords);
+ String title = webDriver.getTitle();
+ List elementList = webDriver.findElements(By.className("gl-i-wrap"));
+ List