当前位置: 代码迷 >> 综合 >> 【B2C-爱购物商城】 开发文档 day10
  详细解决方案

【B2C-爱购物商城】 开发文档 day10

热度:43   发布时间:2023-12-13 14:05:31.0

商品管理 - 上架、下架 + 列表页实现 - 跳转到列表页


一、搭建搜索服务 - 公共模块

1、导入依赖:
在这里插入图片描述

<dependency><groupId>com.zhengqing</groupId><artifactId>basic_util</artifactId><version>1.0-SNAPSHOT</version>
</dependency>
<!--springboot 对 spring data es 的支持-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2、配置:

spring:data:elasticsearch:cluster-name: elasticsearchcluster-nodes: 127.0.0.1:9300  # 注:9200->图形界面端、9300->代码端

在这里插入图片描述

注: 这里暂时先将8010中的bootstrap.yml备份一份bootstrap_bak.yml 然后将github上的配置application-common-dev.yml 里面的内容拷贝到项目中bootstrap.yml本地里 !! -->原因:暂时只能拿到项目本地配置!
在这里插入图片描述

3、编写服务 - 接口层

① ProductDoc

@Document(indexName = "aigou",type = "product")
public class ProductDoc {
    @Idprivate Long id;private Long productTypeId;//类型idprivate Long brandId;//品牌idprivate Integer minPrice;//最小价格private Integer maxPrice;//最大价格private Integer saleCount;//销量private Integer onSaleTime;//上架时间private Integer commentCount;//评论总数private Integer viewCount;//浏览数@Field(type = FieldType.Keyword)List<String> images = new ArrayList<>();//图片@Field(type = FieldType.Text,analyzer = "ik_max_word",searchAnalyzer = "ik_max_word")private String all;//模糊查询所有字段 name、subName、brandName、productTypeName@Field(type = FieldType.Keyword)private String viewProperties;//显示属性@Field(type = FieldType.Keyword)private String skuProperties;//sku属性//getter/setter方法...
}

② feign/fallbackFactory

@FeignClient(value = "AIGOU-COMMON", fallbackFactory = ProductDocClientFallbackFactory.class)
@RequestMapping("/productDoc")
public interface ProductDocClient {
    //crud@RequestMapping(value = "/save",method = RequestMethod.POST)AjaxResult save(ProductDoc productDoc); //添加、修改@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)AjaxResult del(@PathVariable("id") Long id);  //删除@RequestMapping(value = "/{id}",method = RequestMethod.GET)ProductDoc get(@PathVariable("id") Long id); //获取一个//批量操作@RequestMapping(value = "/batchSave",method = RequestMethod.POST)AjaxResult batchSave(@RequestBody List<ProductDoc> productDocs); //批量添加@RequestMapping(value = "/batchDel",method = RequestMethod.DELETE)AjaxResult batchDel(@RequestBody List<Long> ids); //批量上传//分页搜索@RequestMapping(value = "/search",method = RequestMethod.GET)PageList<ProductDoc> search(Map<String,Object> params);  //搜索
}
@Component
public class ProductDocClientFallbackFactory implements FallbackFactory<ProductDocClient>{
    @Overridepublic ProductDocClient create(Throwable throwable) {
    return new ProductDocClient() {
    @Overridepublic AjaxResult save(ProductDoc productDoc) {
    return null;}@Overridepublic AjaxResult del(Long id) {
    return null;}@Overridepublic ProductDoc get(Long id) {
    return null;}@Overridepublic AjaxResult batchSave(List<ProductDoc> productDocs) {
    return null;}@Overridepublic AjaxResult batchDel(List<Long> ids) {
    return null;}@Overridepublic PageList<ProductDoc> search(Map<String, Object> params) {
    return null;}};}
}

4、编写服务层:

① repository

@Repository
public interface ProductDocRepository extends ElasticsearchRepository<ProductDoc,Long> {
    }

② service

public interface IProductDocService {
    void add(ProductDoc productDoc);//添加文档void del(Long id);//删除文档ProductDoc get(Long id);//获取文档void batchAdd(List<ProductDoc> productDocs);//批量添加文档void batchDel(List<Long> ids);//批量删除PageList<ProductDoc> search(Map<String, Object> params);//查询
}
@Service
public class ProductDocServiceImpl implements IProductDocService{
    @Autowiredprivate ProductDocRepository repository;@Overridepublic void add(ProductDoc productDoc) {
    repository.save(productDoc);}@Overridepublic void del(Long id) {
    repository.deleteById(id);}@Overridepublic ProductDoc get(Long id) {
    return  repository.findById(id).get();}@Overridepublic void batchAdd(List<ProductDoc> productDocs) {
    repository.saveAll(productDocs);}@Overridepublic void batchDel(List<Long> ids) {
    for (Long id : ids) {
    repository.deleteById(id);}}@Overridepublic PageList<ProductDoc> search(Map<String, Object> params) {
    return null;}
}

③ controller实现feign

@RestController
@RequestMapping("/productDoc")
public class ProductDocController implements ProductDocClient{
    @Autowiredprivate IProductDocService productDocService;//crud@RequestMapping(value = "/save",method = RequestMethod.POST)public AjaxResult save(ProductDoc productDoc){
    try {
    productDocService.add(productDoc);return AjaxResult.me();} catch (Exception e) {
    e.printStackTrace();return AjaxResult.me().setSuccess(false).setMessage("保存失败!"+e.getMessage());}}@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)public  AjaxResult del(@PathVariable("id") Long id){
    try {
    productDocService.del(id);return AjaxResult.me();} catch (Exception e) {
    e.printStackTrace();return AjaxResult.me().setSuccess(false).setMessage("删除失败!"+e.getMessage());}}@RequestMapping(value = "/{id}",method = RequestMethod.GET)public  ProductDoc get(@PathVariable("id") Long id){
    return productDocService.get(id);}//批量操作@RequestMapping(value = "/batchSave",method = RequestMethod.POST)public  AjaxResult batchSave(@RequestBody List<ProductDoc> productDocs){
    try {
    productDocService.batchAdd(productDocs);return AjaxResult.me();} catch (Exception e) {
    e.printStackTrace();return AjaxResult.me().setSuccess(false).setMessage("保存失败!"+e.getMessage());}}@RequestMapping(value = "/batchDel",method = RequestMethod.DELETE)public AjaxResult batchDel(@RequestBody List<Long> ids){
    try {
    productDocService.batchDel(ids);return AjaxResult.me();} catch (Exception e) {
    e.printStackTrace();return AjaxResult.me().setSuccess(false).setMessage("删除失败!"+e.getMessage());}}//分页搜索@RequestMapping(value = "/search",method = RequestMethod.GET)public PageList<ProductDoc> search(Map<String,Object> params){
    return productDocService.search(params);}
}

④ 创建索引,并且建立类型映射

@RunWith(SpringRunner.class)
@SpringBootTest(classes = CommonApplication_8010.class)
public class ProductDocInitTest {
    @Autowiredprivate ElasticsearchTemplate template;@Test  //创建索引,并且建立类型映射public void testInit() throws Exception {
    template.createIndex(ProductDoc.class); //创建索引template.putMapping(ProductDoc.class); //类型映射-自定义映射}
}

二、上下架处理
在这里插入图片描述
Product.java中修改:

public Long getOnSaleTime() {
    return onSaleTime;
}public void setOnSaleTime(Long onSaleTime) {
    this.onSaleTime = onSaleTime;
}

在这里插入图片描述
mapper:

void onSale(Map<String, Object> params);//上架
void offSale(Map<String, Object> params);//下架

mapper.xml: (注意collection里面是ids)

<update id="onSale" parameterType="map">UPDATE t_product set state = 1, onSaleTime = #{timeStamp} where id in<foreach collection="ids" item="item" open="(" close=")" separator=",">#{item}</foreach>
</update>
<update id="offSale" parameterType="map">UPDATE t_product set state = 0, offSaleTime = #{timeStamp} where id in<foreach collection="ids" item="item" open="(" close=")" separator=",">#{item}</foreach>
</update>

service:

void onSale(String ids, Integer onSale);//上下架处理
@Autowired
private BrandMapper brandMapper;
@Autowired
private ProductTypeMapper productTypeMapper;
@Autowired
private ProductDocClient productDocClient;@Override
public boolean updateById(Product entity) {
    //添加本表信息以外,还要存放关联表entity.setUpdateTime(new Date().getTime());productMapper.updateById(entity);//通过productId查询productExtWrapper<ProductExt> wrapper = new EntityWrapper<ProductExt>().eq("productId", entity.getId());ProductExt productExt = productExtMapper.selectList(wrapper).get(0);//把前台传递进来值设置给数据库查询出来值,并且把它修改进去ProductExt tmp = entity.getProductExt();if ( tmp!= null) {
    productExt.setDescription(tmp.getDescription());productExt.setRichContent(tmp.getRichContent());productExtMapper.updateById(productExt);}// 如果是上架状态,要同步修改es库if (entity.getState()==1){
    ProductDoc productDoc = product2productDoc(entity);productDocClient.save(productDoc);}return true;
}@Override
public boolean deleteById(Serializable id) {
    super.deleteById(id);//如果是上架状态,要同步删除es库Product product = productMapper.selectById(id);if (product.getState()==1){
    productDocClient.del(Long.valueOf(id.toString()));}return true;
}@Override
public void onSale(String ids, Integer onSale) {
    List<Long> idsLong = StrUtils.splitStr2LongArr(ids);if (1==onSale.intValue()){
      //上架//数据库状态和上架时间要修改 id 时间Map<String,Object> params = new HashMap<>();params.put("ids", idsLong);params.put("timeStamp", new Date().getTime());productMapper.onSale(params);//添加esku// productDocClient.batchDel(Arrays.asList(idsLong));List<ProductDoc> productDocs = product2productDocs(idsLong);productDocClient.batchSave(productDocs);}else{
     //下架//数据库状态和下架时间要修改Map<String,Object> params = new HashMap<>();params.put("ids", idsLong);params.put("timeStamp", new Date().getTime());productMapper.offSale(params);//删除eskuproductDocClient.batchDel(idsLong);}
}//转换多个
private List<ProductDoc> product2productDocs(List<Long> ids) {
    List<ProductDoc> productDocs = new ArrayList<>();for (Long id : ids) {
    Product product = productMapper.selectById(id);ProductDoc productDoc = product2productDoc(product);productDocs.add(productDoc);}return productDocs;
}// 转换一个
private ProductDoc product2productDoc(Product product) {
    //选中productDoc -》 alt+enter -》 快速生成set方法赋值ProductDoc productDoc = new ProductDoc();productDoc.setId(product.getId());productDoc.setProductTypeId(product.getProductTypeId());productDoc.setBrandId(product.getBrandId());//从某个商品sku中获取最大或最小List<Sku> skus = skuMapper.selectList(new EntityWrapper<Sku>().eq("productId", product.getId()));Integer minPrice  = skus.get(0).getPrice();Integer maxPrice  = skus.get(0).getPrice();for (Sku sku : skus) {
    if (sku.getPrice()<minPrice) minPrice=sku.getPrice();if (sku.getPrice()>maxPrice) maxPrice = sku.getPrice();}productDoc.setMinPrice(minPrice);productDoc.setMaxPrice(maxPrice);productDoc.setSaleCount(product.getSaleCount());productDoc.setOnSaleTime(product.getOnSaleTime().intValue());productDoc.setCommentCount(product.getCommentCount());productDoc.setViewCount(product.getViewCount());String medias = product.getMedias();if (StringUtils.isNotBlank(medias)) {
    productDoc.setImages(Arrays.asList(medias.split(",")));}Brand brand = brandMapper.selectById(product.getBrandId());ProductType productType = productTypeMapper.selectById(product.getProductTypeId());//投机-有空格就会分词String all = product.getName()+" "+product.getSubName()+" "+brand.getName()+" "+productType.getName();productDoc.setAll(all);productDoc.setViewProperties(product.getViewProperties());productDoc.setSkuProperties(product.getSkuTemplate());//设置值return productDoc;
}

controller:

@RequestMapping(value="/onSale",method= RequestMethod.POST)
public AjaxResult onSale(@RequestBody Map<String,Object> params){
    try {
    String ids = (String) params.get("ids");//1,2,3System.out.println(ids);Integer onSale = Integer.valueOf(params.get("onSale").toString());System.out.println(onSale);productService.onSale(ids,onSale);return AjaxResult.me();} catch (Exception e) {
    e.printStackTrace();return AjaxResult.me().setSuccess(false).setMessage("上下架失败!"+e.getMessage());}
}

三、列表页实现 - 跳转到列表页:

1、主页携带参数跳转到列表页.

location.href = list.html?keyword ==xx

location.href = list.html?productType==154

2、列表页,加载完毕后,获取传递过来keyword ,或者productType

keyword

? ①回显搜索框

? ②以keyword为搜索条件到es中查询分页数据,展示在界面

productType

? ①发送获取面包屑请求,展示在界面

? ②发送品牌请求获取品牌,展示在界面

? ③以productType为搜索条件到es中查询分页数据,展示在界面

修改模板路径: (notepad++ 替换打开所有文件 - 具体见代码…)

在这里插入图片描述

前端代码部分略:见源码即可…

最后启动测试:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

源码和文档: https://pan.baidu.com/s/1FkLU_KPsd79Qci611BK0BQ