SpringBoot使用redis结合mysql数据库(黑名单)渲染商品详情界面

news2024/11/26 7:00:43

目录

一、界面效果

二、前端代码

 三、后端代码(redis+blacklist)

3.1 ProducatController

3.2 ProductService

3.3 ProductDao

 3.4 映射文件


一、界面效果

二、前端代码

商品详情前端代码

<template>
  <van-nav-bar
    title="商品详情"
    left-text="返回"
    right-text="分享"
    left-arrow
    @click-left="onClickLeft"
    @click-right="onClickRight"
  />
  <van-swipe :autoplay="3000" lazy-render>
    <van-swipe-item v-for="image in product.img" :key="image">
      <img :src="image" style="width: 100%; height: 250px" @click="show" />
    </van-swipe-item>
  </van-swipe>
  <div class="Detail">
    <div class="price">
      <div>
        到手价¥<span>{{ product.price }}</span>
      </div>
    </div>
    <h4>{{ product.name }}</h4>
    <van-text-ellipsis
      rows="1"
      :content="product.subName"
      expand-text="展开"
      collapse-text="收起"
    />
  </div>
  <div class="warp">
    <van-tabs v-model:active="active" swipeable>
      <van-tab title="商品介绍">
        <div v-html="product.brief"></div>
      </van-tab>
      <van-tab title="规格参数"> 3333 </van-tab>
      <van-tab title="售后保障">
        <div>
          <div class="mod_tit_line">
            <h3>权利声明</h3>
          </div>
          京东商城上的所有商品信息、客户评价、商品咨询、网友讨论等内容,是京东商城重要的经营资源,未经许可,禁止非法转载使用。
          <div class="for_separator"></div>
          <p>
            <b>注:</b
            >本站商品信息均来自于厂商,其真实性、准确性和合法性由信息拥有者(厂商)负责。本站不提供任何保证,并不承担任何法律责任。
          </p>
        </div>
      </van-tab>
    </van-tabs>
  </div>
  <van-action-bar>
    <van-action-bar-icon icon="chat-o" text="客服" color="#ee0a24" />
    <van-action-bar-icon icon="cart-o" text="购物车" />
    <van-action-bar-icon icon="star" text="已收藏" color="#ff5000" />
    <van-action-bar-button type="warning" text="加入购物车" />
    <van-action-bar-button type="danger" text="立即购买" />
  </van-action-bar>
  <van-share-sheet
    v-model:show="showShare"
    title="立即分享给好友"
    :options="options"
    @select="onSelect"
  />
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { showToast } from "vant";
import { useRoute, useRouter } from "vue-router";
import { productApi } from "@/api/index";
import { showImagePreview } from "vant";

const onClickLeft = () => history.back();
const onClickRight = () => {
  showShare.value = true;
};
const active = ref(0);
const route = useRoute();

onMounted(() => {
  callDetail();
});
const showShare = ref(false);
const options = [
  { name: "微信", icon: "wechat" },
  { name: "微博", icon: "weibo" },
  { name: "复制链接", icon: "link" },
  { name: "分享海报", icon: "poster" },
  { name: "二维码", icon: "qrcode" },
];

const onSelect = (option) => {
  showToast(option.name);
  showShare.value = false;
};
const show = () => {
  showImagePreview({
    images: product.value.img.split(","),
  });
};
const callDetail = () => {
  productApi.selectById.call({ id: route.query.id }).then((res: any) => {
    console.log(res);
    product.value = res;
    product.value.img=res.img.split(',')
  });
};
const product: any = ref({

});
</script>
<style>
.warp img {
  width: 100%;
}
</style>
<style scoped>
.van-action-bar {
  z-index: 50;
}
.price {
  color: red;
  font-size: 14px;
}
.price span {
  font-size: 20px;
}
.Detail {
  background-color: #fff;
  padding: 5px;
  border-radius: 0 0 10px 10px;
}
.Detail h4 {
  margin: 5px 0;
}
.Detail p {
  font-size: 15px;
}
.warp {
  margin-top: 10px;
  background-color: #fff;
  padding: 5px;
  border-radius: 10px 10px 0 0;
}
</style>

 三、后端代码(redis+blacklist)

3.1 ProducatController

    /**
     * 商品详情
     * @param id
     * @return
     */
    @GetMapping("/detail")
    public Product detail(Integer id) {
        int a=10;
        return productService.detail(id);
    }

3.2 ProductService

package com.beimao.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.smart.core.exception.BizException;
import com.beimao.common.model.Product;
import com.beimao.dao.ProductDao;
import com.beimao.dao.ProductMapper;
import com.beimao.model.EsProduct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class ProductService {
    /**
     * redis黑名单解决击穿问题
     */
    
    @Autowired
    private ProductDao productDao;
    @Resource(name = "redisTemplate")
    private HashOperations<String,String,String> hashOperations;
    @Resource(name = "redisTemplate")
    private ValueOperations<String, Product> valueOperations;

    // 黑名单key
    public static final String BLACKLIST_KEY = "product.hei";
    // 商品详情key
    public static final String ProductDetail_KEY = "product.detail";

  
    /**
     * 根据商品id 给商品详情
     * 先从redis中查询,如果redis中没有,则从数据库中查询
     *
     * @param id
     * @return
     */
    public Product detail(Integer id) {
        /**
         * 先验证商品id是否合法
         */
        if (id <= 0) {
            log.debug("商品id=》{}不合法", id);
            throw new BizException(100, "商品id不合法");

        }
        /**
         * 从redis里先检查 黑名单里是否有该商品
         * 如果有,抛出异常
         */
        Boolean b = hashOperations.hasKey(BLACKLIST_KEY, id.toString());
        if (b) {
            log.debug("商品不存在,商品在黑名单里,商品id=>{}", id);
            throw new BizException(101, "商品不存在");
        }
        /**
         * 黑名单没有
         * 直接从redis里查询是否有该商品
         * 有就返回,没有就查数据库
         */
        Product product = valueOperations.get(ProductDetail_KEY+id);
        if (ObjectUtil.isNotEmpty(product)) {
            log.debug("商品id=>{},从redis里查询到商品", id);
            return product;
        }
        /**
         * redis里面没有 就从数据库里面查
         * 数据库有就加入redis里面,没有就加入黑名单
         */
        product = productDao.detail(id);
        if (ObjectUtil.isEmpty(product)) {
            // 数据库查不到就加入黑名单
            hashOperations.put(BLACKLIST_KEY, id.toString(), DateUtil.now());
            log.debug("数据库里没有该商品,商品id=>{}加入黑名单", id);
        }
        // 数据库里面有就将该商品存到redis里面,设置ttl 一天
        /**
         *  错峰解决redis里的雪崩问题
         */
        int expire= RandomUtil.randomInt(-60 , 60);
        valueOperations.set(ProductDetail_KEY+id, product,24*60+expire, TimeUnit.MINUTES);
        return product;
    }

}

3.3 ProductDao

 /**
     * 根据商品id查询商品详情
     * @param id
     * @return
     */
    Product detail(Integer id);

 3.4 映射文件

<!--   根据id查询商品详情-->
    <select id="detail" resultType="com.beimao.common.model.Product">
        select id,subName,status,price,seq,tags,`name`,categoryId,img,brief
        from 205_product where id = #{id}
    </select>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1709016.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu24.04LVM扩容问题

目录 一、 开机前设置&#xff1a;扩展 二、 开机后设置&#xff1a;分区管理 通过gparted管理分区有效做法。 一、 开机前设置&#xff1a;扩展 虚拟机关机。打开虚拟机设置。 挂起状态是不能扩容的 这里选择扩容到40G 二、 开机后设置&#xff1a;分区管理 使用gpar…

md5强弱碰撞

一&#xff0c;类型。 1.弱比较 php中的""和""在进行比较时&#xff0c;数字和字符串比较或者涉及到数字内容的字符串&#xff0c;则字符串会被转换为数值并且比较按照数值来进行。按照此理&#xff0c;我们可以上传md5编码后是0e的字符串&#xff0c;在…

拉格朗日插值及牛顿差商方法的实现(Matlab)

一、问题描述 拉格朗日插值及牛顿差商方法的实现。 二、实验目的 掌握拉格朗日插值和牛顿差商方法的原理&#xff0c;能够编写代码实现两种方法&#xff1b;能够分析多项式插值中的误差。 三、实验内容及要求 利用拉格朗日插值及牛顿差商方法估计1980 年的人口&#xff0c;并…

Docker 基础使用 (1)

文章目录 Docker 软件安装Docker 镜像仓库Docker 仓库指令Docker 镜像指令Docker 容器指令Docker 使用实例 —— 搭建 nginx 服务nginx 概念nginx 使用用 docker 启动 nginx 侧重对docker基本使用的概览。 Docker 软件安装 Linux Ubuntu 依次执行以下指令即可 # 更新软件包列…

Java | Leetcode Java题解之第102题二叉树的层序遍历

题目&#xff1a; 题解&#xff1a; class Solution {public List<List<Integer>> levelOrder(TreeNode root) {Queue<TreeNode> queue new LinkedList<>();List<List<Integer>> res new ArrayList<>();if (root ! null) queue.a…

代码模板,Cookie和Session

目录 代码模板 Cookie的基本使用 概念 Cookie的API public Cookie(String name, String value) 发送Cookie对象到客户端&#xff1a;使用response对象 创建Cookie对象并响应给浏览器 在服务器后端获取Cookie对象 Cookie[]cookiesrequset.getCookies(); Cookie的使用细…

Linux 软件包管理器 yum的下载、功能介绍及使用

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;青果大战linux 总有光环在陨落&#xff0c;总有新星在闪烁 Linux下的三种软件安装方…

香橙派 AiPro通过Micro USB接口进行串口调试

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、配置步骤1.安装CH343驱动2.配置串口参数 二、使用步骤总结 前言 最近在玩一个新玩具香橙派 AiPro&#xff0c;除了通过SSH方式连接开发板以外&#xff0c;…

创新指南|降低 TikTok CPA 的 9 项专家策略

企业在 TikTok 上投放广告&#xff0c;往往最想确保获得最佳的投资回报。然而&#xff0c;这往往说起来容易做起来难。您需要了解如何利用不同的营销工具、定位策略和创意执行来实现您的业务目标并提高成本效率。本文将分享 9 个行之有效的策略&#xff0c;助您有效降低 TikTok…

【介绍下如何在SQL中添加数据】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

Linux——多线程(一)

一、线程的概念 1.1线程概念 教材中的概念&#xff1a; (有问题?) 线程是进程内部的一个执行分支&#xff0c;线程是CPU调度的基本单位 之前我们讲的进程&#xff1a; 加载到内存中的程序&#x…

go-zero 实战(2)

go-zero 实战&#xff08;1&#xff09; 中&#xff0c;使用了go-zero 创建了order 和 user 两个微服务。而order作为grpc的客户端&#xff0c;user 作为grpc的服务端&#xff0c;打通了 order 到 user的调用。接下来&#xff0c;我们在user中&#xff0c;加入mysql组件。确保数…

module ‘plotting‘ has no attribute ‘EpisodeStats‘

plotting.py 的版本不同&#xff0c;可以使用下列版本 reinforcement-learning/lib/plotting.py at master dennybritz/reinforcement-learning GitHubImplementation of Reinforcement Learning Algorithms. Python, OpenAI Gym, Tensorflow. Exercises and Solutions to a…

【Real】[Flask]SSTI

文章目录 前言一、题目解读二、解题过程三、知识点Flask是什么SSTI是什么SSTI是如何形成的易于利用的类payload是什么 探索类型和类层次结构和方法 前言 温馨提示&#xff1a;看到哪里不懂直接跳到知识点部分&#xff0c;理解完再回到解题过程。 一、题目解读 题目是[Flask]S…

winform安装时覆盖原版本并保留配置文件

如何打包参考大佬的博客添加链接描述 覆盖原版本 修改 Properties 下的 AssemblyInfo.cs 中的版本号&#xff0c;如下。原来是1.0.0.0&#xff0c;我修改成1.0.2。 选中 Setup 项目&#xff0c;修改 Version 属性修改 Version 属性后 ProductCode 也会改变&#xff0c;卸载程…

关于k8s集群的污点和容忍,以及k8s集群的故障排查思路

一 污点(Taint) 和 容忍(Tolerations) &#xff08;一&#xff09;污点 在Kubernetes&#xff08;K8s&#xff09;中&#xff0c;污点&#xff08;Taints&#xff09;是一个重要的概念&#xff0c;用于实现Pod的调度控制。以下是关于污点的详细解释&#xff1a;1.污点定义 污点…

SSL协议:网络安全通信的守护者

在网络通信迅猛发展的今天&#xff0c;数据安全和隐私保护变得尤为重要。安全套接层协议&#xff08;Secure Sockets Layer, SSL&#xff09;作为早期网络加密及身份验证的基石&#xff0c;为在线数据传输提供了安全保障。下面我们就来了解一下SSL协议。 SSL协议概述 SSL协议最…

package.json中peerDependencies的使用场景

文章目录 peerDependencies 的使用场景peerDependencies 的使用案例为什么使用 peerDependencies需要注意的事项主要作用 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xf…

(2020|ICML PMLR,线性 Transformer,核函数,RNN)Transformer 是 RNN

Transformers are RNNs: Fast Autoregressive Transformers with Linear Attention 公众号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 3. 线性 Transformers 3.1. Transformer 3.2.…

力扣62 不同路径 Java版本

文章目录 题目描述代码 题目描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少…