“惠医通-医院挂号订单平台”

news2025/1/15 16:40:11

在这里插入图片描述

结合已学习过的vue3和TS完成的项目,便于患者对自己想要就诊的科室进行挂号,付款

一:项目简介

前端技术栈

Vue3

TS

vue-router

Element-ui

Axios

Pinia

项目架构

image-20230828170348965

二:主要模块

1. axios二次封装

1.1 创建实例

//利用axios.create方法创建一个axios实例
const request = axios.create({
    baseURL: '/api', //请求基础路径设置
    timeout: 5000 //超时的时间设置,超出5s请求就是失败
})

1.2 请求拦截器

引入store仓库中的用户token,设置请求头携带token参数,后序请求需要验证token

//请求拦截器
request.interceptors.request.use(config => {
    //config:请求拦截器回调注入的对象(配置对象),配置对象的身上最重要的一件事情headers属性
    //可以通过请求头携带公共参数 -token
    //获取用户仓库
    let userStore = useUserStore()
    // console.log(userStore.userInfo)
    // token: 公共参数,用户登录了需要携带
    if (userStore.userInfo.token) {
        config.headers.token = userStore.userInfo.token
    }

    return config
})

1.3 响应拦截器

利用响应拦截器进行简化数据

当http网络错误时,设置提示信息

//响应拦截器
request.interceptors.response.use(
    response => {
        //响应拦截器成功的回调,一般会简化数据
        return response.data
    },
    error => {
        //处理http网络错误
        let status = error.response.status
        switch (status) {
            case 404:
                //错误信息
                ElMessage({
                    type: 'error',
                    message: '请求失败路径出现问题'
                })
                break
            case 500 | 501 | 502 | 503 | 504 | 505:
                //错误信息
                ElMessage({
                    type: 'error',
                    message: '服务器错误'
                })
                break
            case 401:
                //错误信息
                ElMessage({
                    type: 'error',
                    message: '参数有误'
                })
                break
        }
        return Promise.reject(new Error(error.message))
    }
)

2. vite配置代理跨域

在跨域请求时,浏览器会采取同源策略来限制来自不同源的跨域请求,为了解决这个问题,通常可以采用代理服务器来处理该问题,使得请求在同源的环境下进行

vite服务器会将请求转发到指定的代理服务器,代理服务器再向目标请求地址发起请求

代理服务器接收到真正的响应后,再将其返回给vite服务器,最终返回给前端

    //配置代理跨域
    server: {
        proxy: {
            '/api': {
                target: 'http:xxx.cn',
                changeOrigin: true
            }
        }
    }

3. 首页: 搜索栏

image-20230828172454394

element-ui组件-自动补全输入框

        <el-autocomplete
            @select="goDetail"
            :trigger-on-focus="false"
            clearable
            placeholder="请你输入医院名称"
            v-model="hosname"
            :fetch-suggestions="fetchData"
        />
//引入请求方法
import { reqHospitalInfo } from '@/api/home'
import type { HospitalInfo } from '@/api/home/type'
//创建路由器对象
let $router = useRouter()
//收集搜索的关键字(医院的名字)
let hosname = ref<string>('')

//顶部组件的回调
const fetchData = async (keyword: string, cb: any) => {
    //当用户输入完关键字时 函数执行 发送请求获取需要展示的数据
    // console.log(123)
    let result: HospitalInfo = await reqHospitalInfo(keyword)
    // console.log(result)
    //该组件 需要的数据字段为 value 返回的数据字段为hosname 整理修改
    let showData = result.data.map(item => {
        return {
            value: item.hosname, //展示的是医院的编码
            hoscode: item.hoscode //存储医院的编码
        }
    })
    //给组件提供展示的数据
    cb(showData)
}

//点击某一个推荐项
const goDetail = (item: any) => {
    //点击推荐项目进入医院详情页,将来需要携带query参数(医院的编码)
    // console.log(item)

    $router.push({ path: '/hospital/register', query: { hoscode: item.hoscode } })
}

image-20230828172926766

  • fetch-suggestions方法,需要两个参数,keyword是搜索框输入的参数,cb,callback回调函数,需要将给组件展示的数据传给回调函数
  • 因此,调用根据输入的字段获取医院信息,使用map方法遍历返回的数据,再根据对应的字段将数据返回出来,作为showData,再将其传入回调

image-20230828173723770

  • select事件,当选中对应选项时触发,携带对应医院参数跳转到对应医院详情页

4. 首页: 根据等级和地区筛选

image-20230828174031670

4.1 子组件:Level-医院等级

  • 自定义事件向父组件传递等级参数

  • 子组件通过defineEmits设置要发射给父组件需要使用的方法getLevel

  • 使用defineEmits会返回一个方法,使用一个变量emits(变量名随意)去接收

  • 在对应时机触发事件,并传入需要传递给父组件的参数

    //点击等级的按钮回调
    const changeLevel = (level: string) => {
        //高亮响应式数据存储leve数值
        activeFlag.value = level
        //触发自定义事件: 将医院的等级数值传递给父组件
        $emit('getLevel', level)
    }
    
    let $emit = defineEmits(['getLevel'])
    

4.2 子组件:Region-地区

//点击不同区域按钮回调
const changeRegion = (region: string) => {
    regionFlag.value = region
    //触发自定义事件传值
    $emits('getRegion', region)
}

let $emits = defineEmits(['getRegion'])

4.3 父组件:home-首页

  • 当页面挂载时候,获取医院数据并展示
  • 但当用户选中等级和地区时,需要重新根据对应的参数获取对应的医院数据
  • 因此需要用到地区子组件和等级子组件传递来的对应参数
  • 用到自定义事件接受两个子组件传递的参数
//子组件自定义事件:获取子组件传递的医院等级数据
const getLevel = (level: string) => {
    //更新存储医院等级数据
    hosType.value = level
    //更新完医院等级数据再重新发起请求
    getHospitalInfo()
}
//子组件自定义事件:获取子组件传递的地区数据
const getRegion = (region: string) => {
    //更新存储医院地区数据
    districtCode.value = region
    //更新完医院等级数据再重新发起请求
    getHospitalInfo()
}

5. 登录/退出

image-20230828180304420

//用户登录
const login = async () => {
    //保证表单校验两项都复合条件
    await form.value.validate()
    try {
        //用户登录成功
        await userStore.userLogin(loginParam)
        //关闭对话框
        userStore.visiable = false
        //获取url的query参数
        let redirect = $route.query.redirect
        if (redirect) {
            $router.push(redirect as string)
        } else {
            $router.push('/home')
        }
    } catch (error) {
        ElMessage({
            type: 'error',
            message: (error as Error).message
        })
    }
}
  • 仓库处理登录逻辑,并保存响应状态
        //用户登录请求
        async userLogin(loginParam: any) {
            let result: UserLoginResponseData = await reqUserLogin(loginParam)
            // console.log(loginParam)
            // console.log(result)
            if (result.code === 200) {
                //存储name和token
                this.userInfo = result.data
                //本地存储持久化存储用户信息
                SET_TOKEN(JSON.stringify(this.userInfo))
                return 'ok'
            } else {
                return Promise.reject(new Error(result.message))
            }
        },
//本地存储操作用户信息的方法
export const SET_TOKEN = (userInfo: string) => {
    localStorage.setItem('userInfo', userInfo)
}

export const GET_TOKEN = () => {
    return localStorage.getItem('userInfo')
}

export const REMOVE_TOKEN = () => {
    localStorage.removeItem('userInfo')
}

  • 封装操作用户相关信息持久化存储的相关方法

image-20230828181203029

        //退出登录
        loginOut() {
            //清空仓库的数据
            this.userInfo = { name: '', token: '' }
            //清空本地存储的数据
            REMOVE_TOKEN()
        }
  • 退出登录,清空仓库的数据,清除本地存储数据

6. 挂号

image-20230828181346006

//点击对应日期获取对应数据存储
const changeTime = async (item: string) => {
    workTime.value = item
    //再调用获取医生数据请求
    getDoctorWorkData()
}
//获取当前日期下的医生信息和票价格请求
const getDoctorWorkData = async () => {
    //三个参数
    //医院编号
    let hoscode: string = $route.query.hoscode as string
    //科室编号
    let depcode: string = $route.query.depcode as string
    //工作日期
    let workDate: string = workTime.value.workDate
    //发请求存储数据
    let result: DoctorResponseData = await reqHospitalDoctor(hoscode, depcode, workDate)
    // console.log(result)
    if (result.code === 200) {
        docArr.value = result.data
    }
}
  • workTime存储改日日期,通过点击对应日期,更新workTime的值,然后再次获取医生数据请求,就可以获取选中日期下的号源数据

7. 微信支付:Qrcode

image-20230828190100989

  • 每个订单有对应的订单id,通过对应的订单id获取唯一对应的订单二维码
  • 根据服务器返回的二维码信息通过Qrcode.js生成二维码图片
  • 调用qrcode的相关API库,传入对应的参数
  • 保存生成的二维码图片地址
//打开二维码支付对话框
const openDialog = async () => {
    dialogVisible.value = true
    //获取支付需要使用二维码信息
    let result: QrCode = await reqQrcode($route.query.orderId as string)
    //更具服务器返回二维码信息生成二维码图片
    imgUrl.value = await QRCode.toDataURL(result.data.codeUrl)
    //设置定时器每间隔2s发起请求 查询订单是否支付
    timer.value = setInterval(async () => {
        let result: PayReslt = await reqQueryPayState($route.query.orderId as string)
        if (result.data === true) {
            //关闭对话框
            dialogVisible.value = false
            //提示信息
            ElMessage({
                type: 'success',
                message: '支付成功'
            })
            //清除定时器
            clearInterval(timer.value)
            //再次获取订单详情的数据
            getOrderInfo()
        }
    }, 2000)
}

image-20230828183349488

  • 当打开支付页面时,就要开启定时器,每个两秒发一次请求用于询问订单是否支付
  • 直到支付成功后清除定时器

8. 就诊人管理

8.1 级联选择器选择多级地址信息

image-20230828183639784

 <el-cascader :props="props" v-model="userParams.addressSelected" />
//级联选择器地址信息方法
const props: CascaderProps = {
    lazy: true, //懒加载数据
    //加载级联选择器数据方法
    async lazyLoad(node: any, resolve: any) {
        let result: any = await reqCity(node.data.id || '86')
        //整理数据
        let showData = result.data.map((item: any) => {
            return {
                id: item.id,
                label: item.name,
                value: item.value,
                leaf: !item.hasChildren
            }
        })
        //注入组件需要展示的数据
        resolve(showData)
    }
}
  • props是级联选择器内置配置参数进行设置的对象
  • lazy属性设置为true,表示开启懒加载
  • 定义一个lazyLoad方法,用于加载级联选择器的数据,接受两个参数node和resolve回调
  • node表示当前选中的节点信息,resolve表示用于回调的函数
  • 方法内部通过id获取城市信息,为一级省份
  • 再使用map方法对城市数据进行整理,将id、name、value和是否有子级节点的信息映射到一个新的对象中,并存储在showData数组中
  • 最后,调用resolve函数,将整理后的数据传入,以便组件进行展示

8.2 就诊人信息收集

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rbXCrJoP-1693303620252)(C:/Users/Cai123/AppData/Roaming/Typora/typora-user-images/image-20230828184821995.png)]

image-20230828183537333

//watch监听数据
watch(
    () => userArr.value,
    () => {
        //如果是从预约挂号那里跳转过来 监听数据变化 根据id找到对应要修改的人
        if ($route.query.type === 'edit') {
            let user = userArr.value.find((item: any) => {
                return item.id == $route.query.id
            })

            //收集数据
            Object.assign(userParams, user)
        }
    }
)
  • Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

  • 当在选择就诊人信息时候,点击修改信息按钮,跳转到对应页面,要收集原先的数据信息

  • 需要通过watch监听userArr,判断路径是否是从预约挂号跳转过来的

  • 通过find方法从所有就诊人中找到对应选中修改的就诊人

  • 将其信息通过object.assign方法进行收集并展示

9. 挂号订单

image-20230828185126402

  • 调用接口信息展示即可

10. 路由鉴权

//路由鉴权: 路由守卫
import router from './router'
//引入大仓库
import pinia from '@/store'
//引入进度条
//@ts-ignore
import Nprogress from 'nprogress'
//引入用户相关的仓库
import useUserStore from '@/store/modules/user'
let userStore = useUserStore(pinia)
//引入进度条样式
import 'nprogress/nprogress.css'
//进度条的加载小圆球不要
Nprogress.configure({ showSpinner: false })
//存储用户未登录可以访问路由得路径
let whiteList = [
    '/home',
    '/hospital/register',
    '/hospital/detail',
    '/hospital/notice',
    '/hospital/close',
    '/hospital/search'
]

//前置守卫
router.beforeEach((to, from, next) => {
    //访问路由组件的之前,进度条开始动
    Nprogress.start()
    //动态设置网页左上角的标题
    //@ts-ignore
    document.title = to.meta.title
    //判断用户是否登录-token
    let token = userStore.userInfo.token
    if (token) {
        next()
    } else {
        //用户未登录
        if (whiteList.includes(to.path)) {
            next()
        } else {
            //登录组件
            userStore.visiable = true
            next({ path: '/home', query: { redirect: to.fullPath } })
        }
    }
})

//后置守卫
router.afterEach((to, from) => {
    //访问路由组件成功,进度条消失
    Nprogress.done()
})

三:规范代码格式和提交规范

  • eslint
  • prettier
  • cz-git

3.1 prettier

module.exports = {
  singleQuote: true, // 使用单引号, 默认false(在jsx中配置无效, 默认都是双引号)
  semi: false, // 使用分号, 默认true
  printWidth: 120, //  每行超过多少字符自动换行
  arrowParens: 'avoid', // avoid 能省略括号的时候就省略 例如x => x
  bracketSpacing: true, // 对象中的空格 默认true
  trailingComma: 'none', // all 包括函数对象等所有可选
  tabWidth: 4, // tab缩进大小,默认为2
  useTabs: false, // 使用tab缩进,默认false
  htmlWhitespaceSensitivity: 'ignore',
  // 对象大括号直接是否有空格,默认为true,效果:{ foo: bar }
  bracketSpacing: true
}

3.2 eslint

module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-essential',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended' // 解决ESlint和Prettier冲突
  ],
  overrides: [],
  // 配置支持 vue 和 ts
  parser: 'vue-eslint-parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    parser: '@typescript-eslint/parser'
  },
  plugins: ['vue', '@typescript-eslint'],
  rules: {
    '@typescript-eslint/no-explicit-any': 'off', // 禁止使用该any类型。
    '@typescript-eslint/no-unused-vars': 'off', //禁止未使用的变量
    'vue/valid-template-root': 'off',
    'vue/no-v-html': 'off',
    'prefer-const': 'off',
    '@typescript-eslint/ban-types': 'off',
    '@typescript-eslint/no-empty-function': 'off',
    '@typescript-eslint/ban-ts-comment': 'off',
    'vue/multi-word-component-names': 'off',
    endOfLine: 'off', // 添加忽略换行格式的检查。
    'vue/require-default-prop': 'off' // props 需要设置默认值
  }
}

3.3 commitlintrc.js

// .commitlintrc.js
module.exports = {
  rules: {
    // @see: https://commitlint.js.org/#/reference-rules
  },
  prompt: {
    messages: {
      type: '选择你要提交的类型 :',
      scope: '选择一个提交范围(可选):',
      customScope: '请输入自定义的提交范围 :',
      subject: '填写简短精炼的变更描述 :\n',
      body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
      breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
      footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
      confirmCommit: '是否提交或修改commit ?'
    },
    types: [
      { value: 'feat', name: 'feat:        新增功能 | A new feature', emoji: '✨' },
      { value: 'fix', name: 'fix:         修复缺陷 | A bug fix', emoji: '🐛' },
      { value: 'docs', name: 'docs:        文档更新 | Documentation only changes', emoji: '📄' },
      {
        value: 'style',
        name: 'style:       代码格式 | Changes that do not affect the meaning of the code',
        emoji: '💄'
      },
      {
        value: 'refactor',
        name: 'refactor:    代码重构 | A code change that neither fixes a bug nor adds a feature',
        emoji: '♻️'
      },
      { value: 'perf', name: 'perf:        性能提升 | A code change that improves performance', emoji: '⚡️' },
      { value: 'test', name: 'test:        测试相关 | Adding missing tests or correcting existing tests', emoji: '✅' },
      {
        value: 'build',
        name: 'build:       构建相关 | Changes that affect the build system or external dependencies',
        emoji: '📦️'
      },
      { value: 'ci', name: 'ci:          持续集成 | Changes to our CI configuration files and scripts', emoji: '🎡' },
      { value: 'revert', name: 'revert:      回退代码 | Revert to a commit', emoji: '⏪️' },
      {
        value: 'chore',
        name: 'chore:       其他修改 | Other changes that do not modify src or test files',
        emoji: '🔨'
      }
    ],
    useEmoji: true,
    // scope 类型(定义之后,可通过上下键选择)
    scopes: [
      ['components', '组件相关'],
      ['hooks', 'hook 相关'],
      ['utils', 'utils 相关'],
      ['element-ui', '对 element-ui 的调整'],
      ['styles', '样式相关'],
      ['deps', '项目依赖'],
      ['auth', '对 auth 修改'],
      ['other', '其他修改']
    ].map(([value, description]) => {
      return {
        value,
        name: `${value.padEnd(30)} (${description})`
      }
    }),

    // 是否允许自定义填写 scope,在 scope 选择的时候,会有 empty 和 custom 可以选择。
    allowCustomScopes: true,

    // 跳过要询问的步骤
    skipQuestions: ['body', 'breaking', 'footer'],
    subjectLimit: 100, // subject 限制长度
    // 设置只有 type 选择了 feat 或 fix,才询问 breaking message
    allowBreakingChanges: ['feat', 'fix'],

    issuePrefixs: [
      // 如果使用 gitee 作为开发管理
      { value: 'link', name: 'link:     链接 ISSUES 进行中' },
      { value: 'comment', name: 'comment: 评论 ISSUES' },
      { value: 'closed', name: 'closed:   标记 ISSUES 已完成' }
    ]
  }
}

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

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

相关文章

如何调整DOSBOX软件的运行窗口大小

前言 小编最近正在学习微机原理&#xff0c;碰到一些问题&#xff0c;在安装DOSBOX后&#xff0c;打开应用&#xff0c;会出现运行窗口特别小&#xff0c;字体也很小的情况&#xff0c;使用时会感觉特别费劲&#xff0c;看着特别的不舒服&#xff0c;那么这个时候就需要调整一…

【LeetCode题目详解】第八章 贪心算法 part01 理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和 day31补

贪心算法理论基础 关于贪心算法&#xff0c;你该了解这些&#xff01; 题目分类大纲如下&#xff1a; # 什么是贪心 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 这么说有点抽象&#xff0c;来举一个例子&#xff1a; 例如&#xff0c;有一堆钞票&…

【C#】C#:“指派给常量数组的必须是常量”

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 记录一个有意思的代码片段。 首先&#xff0c;复习一下常量。…

安防监控/磁盘阵列存储/视频汇聚平台EasyCVR调用rtsp地址返回的IP不正确是什么原因?

安防监控/云存储/磁盘阵列存储/视频汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;能对外分发RTSP、RT…

leetcode 563.二叉树的坡度

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;https://leetcode.cn/problems/binary-tree-tilt/description/ 代码&#xff1a; class Solution { public:int childFind(TreeNode* root , int& sumTile) {if (root nullptr) {return 0; // 空树坡度为0}int l…

VBA技术资料MF48:VBA_在Excel中将列号与字母转换

【分享成果&#xff0c;随喜正能量】除非自己的认知获得了改变和刷新&#xff0c;否则&#xff0c;人们常说的“顺应自己的内心”&#xff0c;顺的不过是一颗旧心&#xff0c;一颗惯性的&#xff0c;充满了各种习性的套路之心。与“顺应自己的内心”恰恰相反&#xff0c;人要用…

2023最新独立版校园跑腿校园社区小程序系统源码 | 附教程

2023最新独立版校园跑腿校园社区小程序系统源码 | 附教程 测试环境&#xff1a;NginxPHP7.2MySQL5.6 多校版本&#xff0c;多模块&#xff0c;适合跑腿&#xff0c;外卖&#xff0c;表白&#xff0c;二手&#xff0c;快递等校园服务 源码下载&#xff1a;https://download.c…

二叉搜索树(C++)

二叉搜索树 概念二叉搜索树的应用二叉搜索树的实现K模型基本结构和函数声明接口实现①find——查找关键码②Insert——插入关键码③Erase——删除关键码&#xff08;重点&#xff09;时间复杂度 源码&#xff08;整体&#xff09;非递归递归 KV模型 在使用C语言写数据结构阶段时…

【Linux】进程通信 — 信号(下篇)

文章目录 &#x1f4d6; 前言1. 阻塞信号1.1 信号其他相关常见概念&#xff1a;1.2 sigset_t&#xff1a;1.2 - 1 信号集操作函数 1.3 sigprocmask&#xff1a;1.4 sigpending&#xff1a; 2. 进程处理信号2.1 内核页表和用户页表&#xff1a;2.2 内核态和用户态&#xff1a;2.…

华为OD机试 - VLAN资源池 - 回溯、双指针(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路1、核心思想2、具体解题思路 五、Java算法源码六、效果展示1、输入2、输出 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&…

产品帮助中心对SaaS行业的作用

帮助中心是一款SaaS产品必不可少的一部分&#xff0c;为了帮助用户更好的解决产品相关问题&#xff0c;提高新用户的使用体验&#xff0c;并且引导其更好地使用产品。 所以今天我们就来谈谈帮助中心对SaaS行业的作用&#xff0c;以及制作帮助中心的方法&#xff0c;每个产品帮…

基于 OV5640 的图像采集显示系统(DVP 接口时序逻辑设计)

文章目录 前言一、DVP 接口时序逻辑设计二、基本数据流接收三、像素位置输出四、舍弃前 N 张图像五、系统异常状态恢复控制六、完整代码展示七、仿真代码展示八、仿真波形展示前言 上一节,我们已经完成了 OV5640 初始化逻辑的介绍。接下来,将要开始完成 DVP 接口的时序设计。…

Maven入门教程(一):安装Maven环境

Maven项目对象模型(POM)&#xff0c;可以通过一小段描述信息来管理项目的构建&#xff0c;报告和文档的软件项目管理工具。 ​ 在项目开发中Maven可以对jar包和对工程之间的依赖关系进行管理。maven仓库中存储jar包&#xff0c;可以一次下载&#xff0c;所有项目通用。 1. 安装…

Java项目-苍穹外卖-Day07-redis缓存应用-SpringCache/购物车功能

文章目录 前言缓存菜品问题分析和实现思路缓存菜品数据清理缓存数据功能测试 SpringCache介绍入门案例 缓存套餐 前言 本章节主要是进行用户端的购物车功能开发 和redis作为mysql缓存的应用以及SpringCache的介绍 因为很多人查询数据库会导致mysql的查询效率降低&#xff0c;可…

解读亚马逊云科技语义搜图检索方案

图像检索&#xff08;包括文搜图和图搜图&#xff09;是各个行业中常见的一个应用场景。比如在电商场景中&#xff0c;基于以图搜图做相似商品查找&#xff1b;在云相册场景中&#xff0c;基于文搜图来找寻所需的图像素材。 传统基于标签的图像检索方式&#xff0c;即先使用目标…

压力传感器的性能技术指标

压力传感器采用第四代无线传输方式&#xff0c;加入用高性能的感压芯片&#xff0c;配合先进的电路处理和温度补偿技术&#xff0c;选用不锈钢外壳做隔离防腐&#xff0c;能够测量与接触部分材质相兼容的气体和液体等介质的表压和绝压。 应用场合&#xff1a;如供水、排水、消…

如何空手套白狼?一口气省7K再抓住一个7K起步的工作?

今日话题&#xff0c;教你如何省七千再得到一个七千起步的技能&#xff01;现在网络行业已经是全世界重点发展的目标&#xff0c;开发行业更是各个企业重点培养&#xff0c;但是在学校教的网络知识太基础太老掉牙&#xff1f;报班随便就是小一万该如何是好呢&#xff1f;解决方…

树莓派3b无屏幕登录

如果要无屏登录&#xff0c;烧写时最好设置&#xff0c;勾选WIFI &#xff0c;登录密码&#xff0c;和SSH 树莓派操作系统下载地址 树莓派资源下载 | 树莓派实验室 无屏幕无键盘登录&#xff1a;新版中可能要先SSH登录&#xff0c;然后才能在RASPI-CONFIG中打开串口控制台 登录…

1A快恢复整流二极管型号汇总

快恢复整流二极管是二极管中的一种&#xff0c;开关特性好、反向恢复时间短&#xff0c;在开关电源、PWM脉宽调制器、变频器等电子电路中经常能看到它的身影。快恢复整流二极管的内部结构与普通PN结二极管不同&#xff0c;它属于PIN结型二极管&#xff0c;即在P型硅材料与N型硅…

浏览器渲染机制

学习渡一课程、参考 必须明白的浏览器渲染机制 - 掘金 渲染机制的流程 HTML解析 布局 分层 绘制 分块 光栅化 画 HTML解析 - Parse HTML 解析html会生成一个 dom树和cssom树 document.styleSheets 可以看到cssom树 渲染阻塞 在渲染的过程中&#xff0c;遇到一个scr…