给老婆写的,每日自动推送暖心消息

news2025/1/19 11:31:26

文章の目录

  • 一、起因
  • 二、环境准备
  • 三、创建nestjs项目
  • 四、控制器
  • 五、service服务层
    • 1、获取Access token
    • 2、组装模板消息数据
    • 3、获取下次发工资还有多少天
    • 4、获取距离下次结婚纪念日还有多少天
    • 5、获取距离下次生日还有多少天
    • 6、获取时间日期
    • 7、获取是第几个结婚纪念日
    • 8、获取相恋几年了
    • 9、获取是第几个生日
    • 10、获取天气
    • 11、获取每日一句
    • 12、获取相恋天数
    • 13、发送模板消息
  • 六、定义的数据类型
  • 七、配置文件
    • 1、微信公众号配置
    • 2、特殊时间点设置
    • 3、天气配置
  • 八、微信消息模板
    • 1、正常模板
    • 2、发工资模板
    • 3、生日模板
    • 4、结婚纪念日
  • 九、本地开发
  • 十、展示效果
  • 参考
  • 写在最后


一、起因

在稀土掘金上刷到一篇文章【给女友写的,每日自动推送暖心消息】,每天自动定时发送消息,感觉很有趣,刚好最近在周会上听同事讲用 nodejs框架实现前后端考试系统,自己也通过百度了解到nodejs后端框架排名如图,于是决定尝试一把 nestjs(nodejs框架排第二名) 实现。

在这里插入图片描述

二、环境准备

操作系统:windows、Linux、MacOs
运行环境:Nodejs>=12 v13版本除外

三、创建nestjs项目

使用 Nest CLI 建立新项目非常简单。 在安装好 npm 后,您可以使用下面命令在您的 OS 终端中创建 Nest 项目:

$ npm i -g @nestjs/cli
$ nest new project-name

将会创建 project-name 目录, 安装 node_modules 和一些其他样板文件,并将创建一个 src 目录,目录中包含几个核心文件。

src
 ├── app.controller.spec.ts
 ├── app.controller.ts
 ├── app.module.ts
 ├── app.service.ts
 └── main.ts

以下是这些核心文件的简要概述:

在这里插入图片描述
main.ts 包含一个异步函数,它负责引导我们的应用程序:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

要创建一个 Nest 应用实例,我们使用了 NestFactory 核心类。NestFactory 暴露了一些静态方法用于创建应用实例。 create() 方法返回一个实现 INestApplication 接口的对象。该对象提供了一组可用的方法。 在上面的 main.ts 示例中,我们只是启动 HTTP 服务,让应用程序等待 HTTP 请求。

四、控制器

@Controller('ymn')
export class YmnController {
  constructor(private ymnService: YmnService) {}

  @Get()
  async send(@Res() response: Response) {
    const result = await this.ymnService.sendOut();
    response.status(HttpStatus.OK).send('ok');
  }
}

五、service服务层

// 时间处理
const moment = require('moment');

@Injectable()
export class YmnService {
  constructor(
    private configService: ConfigService,
    private readonly httpService: HttpService,
  ) {}

  /**
   * @method 发送模板消息给媳妇儿
   * @returns any[]
   */
  async sendOut(): Promise<any[]> {
    const token = await this.getToken();
    const data = await this.getTemplateData();
    console.log(data);
    // 模板消息接口文档
    const users = this.configService.get('weixin.users');
    const promise = users.map((id) => {
      data.touser = id;
      return this.toWechart(token, data);
    });
    const results = await Promise.all(promise);
    return results;
  }

  /**
   * @method 获取token
   * @returns string token
   */
  async getToken(): Promise<string> {
    ...
  }

  /**
   * @method 组装模板消息数据
   * @returns dataType 组装完的数据
   */
  async getTemplateData(): Promise<dataType> {
    ...
  }

  /**
   * @method 获取距离下次发工资还有多少天
   * @returns number
   */
  getWageDay(): number {
    ...
  }

  /**
   * @method 获取距离下次结婚纪念日还有多少天
   * @returns number
   */
  getWeddingDay(): number {
    ...
  }

  /**
   * @method 获取距离下次生日还有多少天
   * @returns number
   */
  getbirthday(): number {
    ...
  }

  /**
   * @method 获取时间日期
   * @returns string
   */
  getDatetime(): string {
    ...
  }

  /**
   * @method 获取是第几个结婚纪念日
   * @returns number
   */
  getMarryYear(): number {
    ...
  }

  /**
   * @method 获取相恋几年了
   * @returns number
   */
  getLoveYear(): number {
    ...
  }

  /**
   * @method 获取是第几个生日
   * @returns number
   */
  getBirthYear(): number {
    ...
  }

  /**
   * @method 获取天气
   * @returns
   */
  async getWeather(): Promise<weatherType> {
    ...
  }

  /**
   * @method 获取每日一句
   * @returns string
   */
  async getOneSentence(): Promise<string> {
    ...
  }

  /**
   * @method 获取相恋天数
   * @returns number
   */
  getLoveDay(): number {
    ...
  }

  /**
   * @method 通知微信接口
   * @param token
   * @param data
   * @returns
   */
  async toWechart(token: string, data: dataType): Promise<any> {
    ...
  }
}

1、获取Access token

  /**
   * @method 获取token
   * @returns string token
   */
  async getToken(): Promise<string> {
    const grantType = this.configService.get('weixin.grant_type');
    const appid = this.configService.get('weixin.appid');
    const secret = this.configService.get('weixin.secret');
    // 模板消息接口文档
    const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=${grantType}&appid=${appid}&secret=${secret}`;
    const result = await firstValueFrom(this.httpService.get(url));
    if (result.status === 200) return result.data.access_token as string;
    else return '';
  }

2、组装模板消息数据

  /**
   * @method 组装模板消息数据
   * @returns dataType 组装完的数据
   */
  async getTemplateData(): Promise<dataType> {
    // 判断所需模板
    // 发工资模板 getWageDay === 0       wageDay
    // 结婚纪念日模板 getWeddingDay === 0  weddingDay
    // 生日模板 getbirthday === 0       birthday
    // 正常模板                         daily
    const wageDay = this.getWageDay();
    const weddingDay = this.getWeddingDay();
    const birthday = this.getbirthday();
    const data = {
      topcolor: '#FF0000',
      template_id: '',
      data: {},
      touser: '',
    };
    // 发工资模板
    if (!wageDay) {
      data.template_id = this.configService.get('weixin.wage_day');
      data.data = {
        dateTime: {
          value: this.getDatetime(),
          color: '#cc33cc',
        },
      };
    } else if (!weddingDay) {
      // 结婚纪念日模板
      data.template_id = this.configService.get('weixin.wedding_day');
      data.data = {
        dateTime: {
          value: this.getDatetime(),
          color: '#cc33cc',
        },
        anniversary: {
          value: this.getMarryYear(),
          color: '#ff3399',
        },
        year: {
          value: this.getLoveYear(),
          color: '#ff3399',
        },
      };
    } else if (!birthday) {
      // 生日模板
      data.template_id = this.configService.get('weixin.birthdate');
      data.data = {
        dateTime: {
          value: this.getDatetime(),
          color: '#cc33cc',
        },
        individual: {
          value: this.getBirthYear(),
          color: '#ff3399',
        },
      };
    } else {
      // 正常模板
      data.template_id = this.configService.get('weixin.daily');
      // 获取天气
      const getWeather = await this.getWeather();
      // 获取每日一句
      const message = await this.getOneSentence();
      data.data = {
        dateTime: {
          value: this.getDatetime(),
          color: '#cc33cc',
        },
        love: {
          value: this.getLoveDay(),
          color: '#ff3399',
        },
        wage: {
          value: wageDay,
          color: '#66ff00',
        },
        birthday: {
          value: birthday,
          color: '#ff0033',
        },
        marry: {
          value: weddingDay,
          color: '#ff0033',
        },
        wea: {
          value: getWeather.wea,
          color: '#33ff33',
        },
        tem: {
          value: getWeather.tem,
          color: '#0066ff',
        },
        wind_class: {
          value: getWeather.wind_class,
          color: '#ff0033',
        },
        tem1: {
          value: getWeather.tem1,
          color: '#ff0000',
        },
        tem2: {
          value: getWeather.tem2,
          color: '#33ff33',
        },
        win: {
          value: getWeather.win,
          color: '#3399ff',
        },
        message: {
          value: message,
          color: '#8C8C8C',
        },
      };
    }
    return data;
  }

3、获取下次发工资还有多少天

  /**
   * @method 获取距离下次发工资还有多少天
   * @returns number
   */
  getWageDay(): number {
    const wageDay = this.configService.get('time.wage_day');
    // 获取日期 day
    // 如果在wage号之前或等于wage时,那么就用wage-day
    // 如果在wage号之后,那么就用wage +(当前月总天数 - day)
    // 当日日期day
    const day = moment().date();
    // 当月总天数
    const nowDayTotal = moment().daysInMonth();
    // // 下个月总天数
    let resultDay = 0;
    if (day <= wageDay) resultDay = wageDay - day;
    else resultDay = wageDay + (nowDayTotal - day);
    return resultDay;
  }

4、获取距离下次结婚纪念日还有多少天

  /**
   * @method 获取距离下次结婚纪念日还有多少天
   * @returns number
   */
  getWeddingDay(): number {
    const weddingDay = this.configService.get('time.wedding_day');
    // 获取当前时间戳
    const now = moment(moment().format('YYYY-MM-DD')).valueOf();
    // 获取纪念日 月-日
    const mmdd = moment(weddingDay).format('-MM-DD');
    // 获取当年
    const y = moment().year();
    // 获取今年结婚纪念日时间戳
    const nowTimeNumber = moment(y + mmdd).valueOf();
    // 判断今天的结婚纪念日有没有过,如果已经过去(now>nowTimeNumber),resultMarry日期为明年的结婚纪念日
    // 如果还没到,则结束日期为今年的结婚纪念日
    let resultMarry = nowTimeNumber;
    if (now > nowTimeNumber) {
      // 获取明年纪念日
      resultMarry = moment(y + 1 + mmdd).valueOf();
    }
    return moment(moment(resultMarry).format()).diff(
      moment(now).format(),
      'day',
    );
  }

5、获取距离下次生日还有多少天

  /**
   * @method 获取距离下次生日还有多少天
   * @returns number
   */
  getbirthday(): number {
    const birthdate = this.configService.get('time.birthdate');
    // 获取当前时间戳
    const now = moment(moment().format('YYYY-MM-DD')).valueOf();
    // 获取当年
    const y = moment().year();
    // 获取纪念日 月
    const m = moment(birthdate).month();
    // 获取纪念日 日
    const d = moment(birthdate).date();
    // 获取今年生日阳历
    const nowBirthday = lunisolar
      .fromLunar({
        year: y,
        month: m + 1,
        day: d,
      })
      .format('YYYY-MM-DD');
    // 获取今年生日时间戳
    const nowTimeNumber = moment(nowBirthday).valueOf();
    // 判断生日有没有过,如果已经过去(now>nowTimeNumber),resultBirthday日期为明年的生日日期
    // 如果还没到,则结束日期为今年的目标日期
    let resultBirthday = nowTimeNumber;
    if (now > nowTimeNumber) {
      // 获取明年生日阳历
      const nextBirthday = lunisolar
        .fromLunar({
          year: y + 1,
          month: m + 1,
          day: d,
        })
        .format('YYYY-MM-DD');
      // 获取明年目标日期
      resultBirthday = moment(nextBirthday).valueOf();
    }
    return moment(moment(resultBirthday).format()).diff(
      moment(now).format(),
      'day',
    );
  }

6、获取时间日期

  /**
   * @method 获取时间日期
   * @returns string
   */
  getDatetime(): string {
    const week = {
      1: '星期一',
      2: '星期二',
      3: '星期三',
      4: '星期四',
      5: '星期五',
      6: '星期六',
      0: '星期日',
    };
    return moment().format('YYYY年MM月DD日 ') + week[moment().weekday()];
  }

7、获取是第几个结婚纪念日

  /**
   * @method 获取是第几个结婚纪念日
   * @returns number
   */
  getMarryYear(): number {
    const weddingDay = this.configService.get('time.wedding_day');
    return moment().year() - moment(weddingDay).year();
  }

8、获取相恋几年了

  /**
   * @method 获取相恋几年了
   * @returns number
   */
  getLoveYear(): number {
    const loveDay = this.configService.get('time.love');
    return moment().year() - moment(loveDay).year();
  }

9、获取是第几个生日

  /**
   * @method 获取是第几个生日
   * @returns number
   */
  getBirthYear(): number {
    const birthdate = this.configService.get('time.birthdate');
    return moment().year() - moment(birthdate).year();
  }

10、获取天气

  /**
   * @method 获取天气
   * @returns
   */
  async getWeather(): Promise<weatherType> {
    try {
      const dataType = this.configService.get('weather.data_type');
      const ak = this.configService.get('weather.ak');
      const districtId = this.configService.get('weather.district_id');
      // https://api.map.baidu.com/weather/v1/?district_id=130128&data_type=all&ak=bGjmaBLLzlBZXTiAkOwSqiVjftZlg17O
      const url = `https://api.map.baidu.com/weather/v1/?district_id=${districtId}&data_type=${dataType}&ak=${ak}`;
      const result: any = await firstValueFrom(this.httpService.get(url));
      // "wea": "多云",
      // "tem": "27", 实时温度
      // "tem1": "27", 高温
      // "tem2": "17", 低温
      // "win": "西风",
      // "air_level": "优",
      if (result && result.data && result.data.status === 0) {
        const now = result.data.result.now;
        const forecasts = result.data.result.forecasts[0];
        return {
          wea: now.text,
          tem: now.temp,
          tem1: forecasts.high,
          tem2: forecasts.low,
          win: now.wind_dir,
          wind_class: now.wind_class,
        };
      }
    } catch (error) {
      return {
        wea: '未知',
        tem: '未知',
        tem1: '未知',
        tem2: '未知',
        win: '未知',
        wind_class: '未知',
      };
    }
  }

11、获取每日一句

  /**
   * @method 获取每日一句
   * @returns string
   */
  async getOneSentence(): Promise<string> {
    const url = 'https://v1.hitokoto.cn/';
    const result = await firstValueFrom(this.httpService.get(url));
    if (result && result.status === 200) return result.data.hitokoto;
    else return '今日只有我爱你!';
  }

12、获取相恋天数

  /**
   * @method 获取相恋天数
   * @returns number
   */
  getLoveDay(): number {
    const loveDay = this.configService.get('time.love');
    return moment(moment().format('YYYY-MM-DD')).diff(loveDay, 'day');
  }

13、发送模板消息

  /**
   * @method 通知微信接口
   * @param token
   * @param data
   * @returns
   */
  async toWechart(token: string, data: dataType): Promise<any> {
    // 模板消息接口文档
    const url = `https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${token}`;
    const result = await firstValueFrom(this.httpService.post(url, data));
    return result;
  }

六、定义的数据类型

interface dataItemType {
  value: string;
  color: string;
}

export interface dataType {
  topcolor: string;
  template_id: string;
  touser: string;
  data: Record<any, dataItemType>;
}

export interface weatherType {
  wea: string;
  tem: string;
  tem1: string;
  tem2: string;
  win: string;
  wind_class: string;
}

七、配置文件

配置方法参考配置

1、微信公众号配置

因个人只能申请订阅号,而订阅号不支持发送模板消息,所以在此使用的测试的微信公众号,有微信号都可以申请,免注册,扫码登录

无需公众帐号、快速申请接口测试号

直接体验和测试公众平台所有高级接口

申请地址

import { registerAs } from '@nestjs/config';

export default registerAs('weixin', () => ({
  grant_type: '*',
  appid: '*',
  secret: '*',
  users: ['*'],// 用户的openid
  wage_day: '*',// 工资日模板
  wedding_day: '*',// 结婚纪念日模板
  birthdate: '*',// 生日模板
  daily: '*',// 普通模板
}));

2、特殊时间点设置

import { registerAs } from '@nestjs/config';

// 时间
export default registerAs('time', () => ({
  wage_day: 10, // 工资日
  wedding_day: '*',// 结婚纪念日
  birthdate: '*',// 生日阴历
  love: '*',// 相爱日期
}));

3、天气配置

import { registerAs } from '@nestjs/config';

export default registerAs('weather', () => ({
  data_type: 'all',
  ak: '*',
  district_id: '110100',
}));

八、微信消息模板

这个需要在上文提到的 微信公众平台测试账号 单独设置

以下是我用的模板

1、正常模板

{{dateTime.DATA}} 
今天是 我们相恋的第{{love.DATA}}天 
距离上交工资还有{{wage.DATA}}天 
距离你的生日还有{{birthday.DATA}}天 
距离我们结婚纪念日还有{{marry.DATA}}天 
今日天气 {{wea.DATA}} 
当前温度 {{tem.DATA}}度 
最高温度 {{tem1.DATA}}度 
最低温度 {{tem2.DATA}}度 
风向 {{win.DATA}} 
风力等级 {{wind_class.DATA}} 
每日一句 
{{message.DATA}}

2、发工资模板

{{dateTime.DATA}}
老婆大人,今天要发工资了,预计晚九点前会准时上交,记得查收!

3、生日模板

{{dateTime.DATA}}
听说今天是你人生当中第 {{individual.DATA}} 个生日?天呐,
我差点忘记!因为岁月没有在你脸上留下任何痕迹。
尽管,日历告诉我:你又涨了一岁,但你还是那个天真可爱的小妖女,生日快乐!

4、结婚纪念日

{{dateTime.DATA}}
今天是结婚{{anniversary.DATA}}周年纪念日,在一起{{year.DATA}}年了,
经历了风风雨雨,最终依然走在一起,很幸运,很幸福!我们的小家庭要一直幸福下去。

九、本地开发

$ yarn
$ yarn start:dev

十、展示效果

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

参考

  1. node.js 后端框架star 排名 2023年2月更新
  2. 给女友写的,每日自动推送暖心消息

写在最后

如果你感觉文章不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果你觉得该文章有一点点用处,可以给作者点个赞;\\*^o^*//
如果你想要和作者一起进步,可以微信扫描二维码,关注前端老L~~~///(^v^)\\\~~~
谢谢各位读者们啦(^_^)∠※!!!

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

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

相关文章

前端面试题JS篇(4)

浏览器缓存 浏览器缓存分为强缓存和协商缓存&#xff0c;当客户端请求某个资源时&#xff0c;获取缓存的流程如下&#xff1a; 先根据这个资源的一些 http header 判断它是否命中强缓存&#xff0c;如果命中&#xff0c;则直接从本地获取缓存资源&#xff0c;不会发请求到服务…

vivado xpm 使用和封装

vivado xpm 使用和封装 tools -> language templates

【JavaScript】WebAPI入门到实战

文章目录 一、WebAPI背景知识1. 什么是WebAPI&#xff1f;2. 什么是API&#xff1f; 二、DOM基本概念三、获取元素三、事件初识1. 点击事件2. 键盘事件 四、操作元素1. 获取/修改元素内容2. 获取/修改元素属性3. 获取/修改表单元素属性4. 获取/修改样式属性 五、操作节点1. 新增…

scratch还原轨迹 2023年5月中国电子学会图形化编程 少儿编程 scratch编程等级考试四级真题和答案解析

目录 scratch还原轨迹 一、题目要求 1、准备工作 2、功能实现 二、案例分析

Python:安装Flask web框架hello world

安装easy_install pip install distribute 安装pip easy_install pip 安装 virtualenv pip install virtualenv 激活Flask pip install Flask 创建web页面demo.py from flask import Flask app Flask(__name__)app.route(/) def hello_world():return Hello World! 2023if _…

基于springboot实现的rabbitmq消息确认

概述 RabbitMQ的消息确认有两种。 一种是消息发送确认。这种是用来确认生产者将消息发送给交换器&#xff0c;交换器传递给队列的过程中&#xff0c;消息是否成功投递。发送确认分为两步&#xff0c;一是确认是否到达交换器&#xff0c;二是确认是否到达队列。 第二种是消费接…

【APUE】标准I/O库

目录 1、简介 2、FILE对象 3、打开和关闭文件 3.1 fopen 3.2 fclose 4、输入输出流 4.1 fgetc 4.2 fputc 4.3 fgets 4.4 fputs 4.5 fread 4.6 fwrite 4.7 printf 族函数 4.8 scanf 族函数 5、文件指针操作 5.1 fseek 5.2 ftell 5.3 rewind 6、缓冲相关 6.…

安装samba服务器

1.实验目的 &#xff08;1&#xff09;了解SMB和NETBIOS的基本原理 &#xff08;2&#xff09;掌握Windows和Linux之间&#xff0c;Linux系统之间文件共享的基本方法。 2.实验内容 &#xff08;1&#xff09;安装samba服务器。 &#xff08;2&#xff09;配置samba服务器的…

Visual Studio 线性表的链式存储节点输出引发异常:读取访问权限冲突

问题&#xff1a; 写了一个线性表的链式存储想要输出&#xff0c;能够输出&#xff0c;但是会报错&#xff1a;读取访问权限冲突 分析&#xff1a; 当我们输出到最后倒数第二个节点时&#xff0c;p指向倒数第二个节点并输出&#xff1b; 下一轮循环&#xff1a;p指向倒数第二…

Helm Kubernetes Offline Deploy Rancher v2.7.5 Demo (helm 离线部署 rancher 实践)

文章目录 1. 简介2. 预备条件3. 选择 SSL 配置4. 离线安装的 Helm Chart 选项5. 下载介质6. 生成证书7. 镜像入库8. 安装 rancher9. 配置 nodeport10. 配置 ingress11. 界面访问11.1 首页预览11.2 查看集群信息11.3 查看项目空间11.4 查看节点信息 1. 简介 Rancher 是一个开源…

17-数据结构-查找-(顺序、折半、分块)

简介&#xff1a;查找&#xff0c;顾名思义&#xff0c;是我们处理数据时常用的操作之一。大概就是我们从表格中去搜索我们想要的东西&#xff0c;这个表格&#xff0c;就是所谓的查找表&#xff08;存储数据的表&#xff09;。而我们怎么设计查找&#xff0c;才可以让计算机更…

lv4 嵌入式开发-4 标准IO的读写(二进制方式)

目录 1 标准I/O – 按对象读写 2 标准I/O – 小结 3 标准I/O – 思考和练习 文本文件和二进制的区别&#xff1a; 存储的格式不同&#xff1a;文本文件只能存储文本。除了文本都是二进制文件。 补充计算机内码概念&#xff1a;文本符号在计算机内部的编码&#xff08;计算…

2023/09/10

文章目录 1. 使用Vue单页面全局变量注意事项2. 伪元素和伪类3. Vue3中定义数组通常使用ref4. Vue Router的 $router 和 $route5. Vue路由中的query和params的区别6. vue3defineExpose({})属性不能重命名&#xff0c;方法可以重命名7. 显卡共享内存的原理8. deltaY9. 快速生成方…

电池2RC模型 + 开路电压法 + 安时积分 + 电池精度测试 + HPPC脉冲

电池2RC模型 电池2RC模型是一种等效电路模型&#xff0c;用于描述电池的动态特性。该模型将电池视为一个理想电容器和一个理想电阻的并联&#xff0c;其中理想电容器代表电池的化学反应&#xff0c;理想电阻代表电池的内阻。该模型适用于描述电池的充电和放电过程。 开路电压…

Java中如何判断字符串输入[hello,world]是不是字符串数组参数

Java中如何判断字符串输入[hello,world]是不是字符串数组参数&#xff1f; 在Java中&#xff0c;可以使用正则表达式来判断一个字符串是否符合字符串数组的参数格式。你可以使用matches()方法和对应的正则表达式进行判断。 以下是一个示例代码&#xff1a; public static bo…

SpringCloudGateway网关实战(二)

SpringCloudGateway网关实战&#xff08;二&#xff09; 本文我们在前文的基础上&#xff0c;开始讲gateway过滤器的部分内容。gateway的过滤器分为内置过滤器Filter和全局过滤器GlobalFilter。本章节先讲内置过滤器Filter。 需要先声明一下内置过滤器和全局过滤器之间的区别…

mysql文档--innodb中的重头戏--事务隔离级别!!!!--举例学习--现象演示

阿丹&#xff1a; 先要说明一点就是在网上现在查找的mysql中的事务隔离级别其实都是在innodb中的事务隔离级别。因为在mysql的5.5.5版本后myisam被innodb打败&#xff0c;从此innodb成为了mysql中的默认存储引擎。所以在网上查找的事务隔离级别基本上都是innodb的。并且支持事务…

JavaScript基础10——获取数据类型、类型转换

哈喽&#xff0c;大家好&#xff0c;我是雷工。 现如今知识大爆炸&#xff0c;到处都有海量的知识&#xff0c;常常见了就收藏&#xff0c;把网盘塞得满满的&#xff0c;却从来没有看过。 收藏起来装到网盘里并没有什么软用&#xff0c;要把知识装到脑袋里才行。 从几分钟开始&…

【LeetCode-中等题】26. 删除有序数组中的重复项

文章目录 题目方法一&#xff1a;快慢指针 题目 方法一&#xff1a;快慢指针 class Solution { //快慢指针public int removeDuplicates(int[] nums) {int fast 1;int slow 0;while(fast < nums.length){if(nums[fast] nums[fast-1]) fast;//若当前元素和之前元素相同 则…

华为OD机试 - 战场索敌 - 深度优先搜索dfs算法(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、深度优先搜索dfs五、解题思路六、Java算法源码七、效果展示1、输入2、输出3、说明4、如果增加目标敌人数量K为55、来&#xff0c;上强度 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 有一个大小是N*M…