预约功能的知识整理
前置知识
如果项目为小程序的开发项目中:
我们确定数据库中有的字段有: 预约人姓名、手机号、家人名称、预约时间
根据我们的经定一表必须要有的6个字段:
主键、创建时间、修改时间、创建人、修改人、备注
使用我们现在有的字段为:
主键、 预约人姓名、手机号、家人姓名、预约时间、创建时间、修改时间、创建人、修改人、备注
预约的状态也有4种,具体如下:
- 待报道 预约成功后
- 已完成
- 取消
- 过期
所以,预约表中最终的表字段为:
主键、 预约人姓名、手机号、家人姓名、类型、状态、预约时间、创建时间、修改时间、创建人、修改人、备注
由于一个手机号在同一个时间段内只能预约一次,我们也可以在表结构中设置唯一约束(手机号+时间)
我们可以得到如下的预约表 reservation:
CREATE TABLE `reservation` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '预约人姓名',`mobile` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '预约人手机号',`time` datetime NOT NULL COMMENT '预约时间',`visitor` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '探访人',`type` int NOT NULL COMMENT '预约类型,0:参观预约,1:探访预约',`status` int NOT NULL COMMENT '预约状态,0:待报道,1:已完成,2:取消,3:过期',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime DEFAULT NULL COMMENT '更新时间',`create_by` bigint DEFAULT NULL COMMENT '创建人id',`update_by` bigint DEFAULT NULL COMMENT '更新人id',`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '备注',PRIMARY KEY (`id`) USING BTREE,UNIQUE KEY `name_mobile_time_visitor` (`mobile`,`time`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=93 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='预约信息表';
接口的常见实现与操作
1. 新增预约 /customer/reservation/
请求的方法:post
请求参数:
{"mobile": "", //手机号"name": "", //预约人"time": "", //时间"type":0, //预约类型 0为参观预约"visitor": "" //家人
}
我们可以通过一个dto对象传递
实现思路:
1.1 Controller:
/*** 新增预约* @param reservationDto* @return*/@PostMappingpublic ResponseResult addReservation(@RequestBody ReservationDto reservationDto){reservationService.addReservation(reservationDto);return ResponseResult.success();}
1.2 impl:
(1)根据userid 判断今天的取消的次数
(2)进行预约,插入状态
/*** 新增预约信息* @param reservationDto*/@Overridepublic void addReservation(ReservationDto reservationDto) {// 1. 查看数据库的表// 获取当前的useridLong userId = UserThreadLocal.getUserId();// 判断今天取消的次数是否大于3次Long cancelledCount = cancelledCount(userId);// 如果大于3次则不进行预约if(cancelledCount >=3 ){throw new RuntimeException(String.valueOf(BasicEnum.RESERVATION_CANCEL_COUNT_UPPER_LIMIT));}// 进行预约Reservation reservation = new Reservation();BeanUtils.copyProperties(reservationDto,reservation);// 预约状态,0:待报道reservation.setStatus(ReservationStatus.PENDING.getOrdinal());reservation.setCreateBy(userId);try {reservationMapper.insert(reservation);}catch (Exception e){log.info(e + "");throw new RuntimeException(String.valueOf(BasicEnum.TIME_ALREADY_RESERVATED_BY_PHONE));}}
1.3 mapper.xml 进行新增操作
<insert id="insert" parameterType="com.zzyl.entity.Reservation">insert into reservation(name, mobile, time, visitor, type, status, create_by, remark, create_time)values (#{name}, #{mobile}, #{time}, #{visitor}, #{type}, #{status}, #{createBy}, #{remark}, #{createTime})</insert>
2. 分页查询 /customer/reservation/page
请求方式: GET
请求参数:
| 参数名称 | 参数说明 | 数据类型 |
| pageNum | 页码 | int |
| pageSize | 每页数量 | int |
| status | 状态 | int |
实现思路:
2.1 controller
@GetMapping("/page")public ResponseResult<PageResponse<ReservationVo>> getPage(@RequestParam(defaultValue = "1") int pageNum,@RequestParam(defaultValue = "10") int pageSize,@RequestParam(required = false) String name,@RequestParam(required = false) String phone,@RequestParam(required = false) Integer status,@RequestParam(required = false) Integer type,@RequestParam(required = false) Long startTime,@RequestParam(required = false) Long endTime){PageResponse<ReservationVo> byPage = reservationService.findByPage(pageNum, pageSize, name, phone, status, type,ObjectUtil.isEmpty(startTime)? null : LocalDateTimeUtil.of(startTime),ObjectUtil.isEmpty(endTime)? null : LocalDateTimeUtil.of(endTime));return success(byPage);}
2.2 impl 根据分页插件 与 userid进行查询
/*** 分页查询预约* @param pageNum* @param pageSize* @param name* @param phone* @param status* @param type* @param startTime* @param endTime* @return*/@Overridepublic PageResponse<ReservationVo> findByPage(int pageNum, int pageSize, String name, String phone, Integer status, Integer type, LocalDateTime startTime, LocalDateTime endTime) {PageHelper.startPage(pageNum,pageSize);Long userId = UserThreadLocal.getUserId();Page<Reservation> page = reservationMapper.findByPage(pageNum,pageSize,name, phone, status, type, userId, startTime, endTime);return PageResponse.of(page,ReservationVo.class);}
2.3 mapper.xml 实现 用动态Sql进行实现
<select id="findByPage" parameterType="java.util.Map" resultType="com.zzyl.entity.Reservation">select r.id, r.name, r.mobile, r.time, r.visitor, r.type, r.status, r.create_by, r.remark, r.create_time, s.nameas creator from reservation rLEFT JOIN member s ON s.id = r.create_by<where><if test="name != null and name != ''">and r.name like concat('%',#{name},'%')</if><if test="mobile != null and mobole != ''">and r.mobile = #{mobile}</if><if test="status != null">and r.status = #{status,jdbcType=INTEGER}</if><if test="createBy != null">and r.create_by = #{createBy}</if><if test="startTime != null and endTime != null">and r.time BETWEEN #{startTime} and #{endTime}</if></where>order by create_time desc</select>
3. 取消预约
-
请求方式:
PUT /customer/reservation/{id}/cancel -
请求参数:
| 参数名称 | 参数说明 | 数据类型 |
| id | 主键 | long |
实现思路:
3.1 Impl
/*** 取消预约* @param id*/@Overridepublic void cancelledById(Long id) {Reservation reservation = reservationMapper.findById(id);if(ObjectUtil.isNotEmpty(reservation)){// 2:取消reservation.setStatus(ReservationStatus.CANCELED.getOrdinal());reservationMapper.update(reservation);}}
3.2 xml
<update id="update">update reservationset name = #{name},mobile = #{mobile},time = #{time},visitor = #{visitor},type = #{type},status = #{status},update_time = #{updateTime},update_by = #{updateBy}where id = #{id}</update>
4. 查询取消预约数量
-
请求方式:
GET -
请求参数: 无,我们需要获取线程中的用户即可,在后端获取,不需要前端传任何参数
实现思路:
4.1 Impl 获取一天的时间 与 userId
/*** 取消的次数* @param userId* @return*/@Overridepublic Long cancelledCount(Long userId) {// 1.查看今天内取消的次数// 需要给时间范围LocalDateTime startTime = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);LocalDateTime endTime = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59);Long count = reservationMapper.getcancelledCount(startTime,endTime,userId);return count;}
4.2 xml
<select id="getcancelledCount" resultType="java.lang.Long">select count(*) from reservationwhere update_time between #{startTime} and #{endTime}and status = 2and update_by = #{userId}</select>
5. 查询每个时间段剩余预约次数
-
接口地址:
/customer/reservation/countByTime -
请求方式:
GET -
请求参数:
| 参数名称 | 参数说明 | 数据类型 |
| time | 时间 | long(时间戳) |
-
返回示例:
{ "code": 200, "msg": "操作成功","data": [ { "time": "2023-08-21 09:30:00", "count": 5 },{ "time": "2023-08-21 10:00:00", "count": 5 } ],"operationTime": null }
实现思路:
5.1 impl
/*** 查询每个时间剩余的预约次数* @param time* @return*/@Overridepublic List<CountVo> getCountByTime(LocalDateTime time) {LocalDateTime endTime = time.plusHours(24);List<CountVo> list = reservationMapper.getCountByTime(time, endTime);return reservationMapper.getCountByTime(time,endTime);}
5.2 mapper
<select id="getCountByTime" resultType="com.zzyl.vo.CountVo">SELECT time, 6 - COUNT(*) AS countFROM reservationWHERE `time` BETWEEN #{startTime}AND #{endTime}and status != 2GROUP BY time</select>
代码实例:
package com.zzyl.controller.customer;import cn.hutool.core.date.LocalDateTimeUtil;
import com.zzyl.base.PageResponse;
import com.zzyl.base.ResponseResult;
import com.zzyl.controller.BaseController;
import com.zzyl.dto.ReservationDto;
import com.zzyl.service.ReservationService;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.utils.UserThreadLocal;
import com.zzyl.vo.CountVo;
import com.zzyl.vo.ReservationVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;@RestController
@RequestMapping("/customer/reservation")
@Api(tags = "客户预约管理")
public class CustomerReservationController extends BaseController {@Autowiredprivate ReservationService reservationService;/*** 查询每个时间段剩余的预约次数* @param time* @return*/@ApiOperation("查询每个时间段剩余的预约次数")@GetMapping("/countByTime")public ResponseResult getCountByTime(@RequestParam(required = false) Long time){List<CountVo> list = reservationService.getCountByTime(LocalDateTimeUtil.of(time));System.out.println("time --------------------------+ " + time);System.out.println("LocalDateTimeUtil.of(time) --------------+"+LocalDateTimeUtil.of(time));System.out.println("list ----+"+list);return success(list);}/*** 查询预约的次数* @return*/@GetMapping("/cancelled-count")public ResponseResult cancelledCount(){// 1. 获取ThreadLocal中的用户的idLong userId = UserThreadLocal.getUserId();Long count = reservationService.cancelledCount(userId);return ResponseResult.success(count);}/*** 新增预约* @param reservationDto* @return*/@PostMappingpublic ResponseResult addReservation(@RequestBody ReservationDto reservationDto){reservationService.addReservation(reservationDto);return ResponseResult.success();}/*** 分页查询* @param pageNum* @param pageSize* @param name* @param phone* @param status* @param type* @param startTime* @param endTime* @return*/@GetMapping("/page")public ResponseResult<PageResponse<ReservationVo>> getPage(@RequestParam(defaultValue = "1") int pageNum,@RequestParam(defaultValue = "10") int pageSize,@RequestParam(required = false) String name,@RequestParam(required = false) String phone,@RequestParam(required = false) Integer status,@RequestParam(required = false) Integer type,@RequestParam(required = false) Long startTime,@RequestParam(required = false) Long endTime){PageResponse<ReservationVo> byPage = reservationService.findByPage(pageNum, pageSize, name, phone, status, type,ObjectUtil.isEmpty(startTime)? null : LocalDateTimeUtil.of(startTime),ObjectUtil.isEmpty(endTime)? null : LocalDateTimeUtil.of(endTime));return success(byPage);}@PutMapping("/{id}/cancel")public ResponseResult cancelById(@PathVariable Long id){reservationService.cancelledById(id);return success();}
}
public interface ReservationService {Long cancelledCount(Long userId);public List<CountVo> getCountByTime(LocalDateTime time);void addReservation(ReservationDto reservationDto);PageResponse<ReservationVo> findByPage(int pageNum, int pageSize, String name, String phone, Integer status, Integer type, LocalDateTime startTime, LocalDateTime endTime);void cancelledById(Long id);void update(Long id, ReservationDto dto);void updateVisitReservationStatusToExpiredIfNotCompleted(Long id);ReservationVo findById(Long id);void visit(Long id, Long time);void updateReservationStatus(LocalDateTime now);List<ReservationVo> findAll(String mobile, LocalDateTime time);
}
package com.zzyl.service.impl;import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.dto.ReservationDto;
import com.zzyl.dto.VisitDto;
import com.zzyl.entity.Reservation;
import com.zzyl.enums.BasicEnum;
import com.zzyl.enums.ReservationStatus;
import com.zzyl.mapper.ReservationMapper;
import com.zzyl.service.ReservationService;
import com.zzyl.service.VisitService;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.utils.UserThreadLocal;
import com.zzyl.vo.CountVo;
import com.zzyl.vo.ReservationVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;@Service
@Slf4j
public class ResercationServiceImpl implements ReservationService {@Autowiredprivate ReservationMapper reservationMapper;@Autowiredprivate VisitService visitService;/*** 取消的次数* @param userId* @return*/@Overridepublic Long cancelledCount(Long userId) {// 1.查看今天内取消的次数// 需要给时间范围LocalDateTime startTime = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);LocalDateTime endTime = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59);Long count = reservationMapper.getcancelledCount(startTime,endTime,userId);return count;}/*** 查询每个时间剩余的预约次数* @param time* @return*/@Overridepublic List<CountVo> getCountByTime(LocalDateTime time) {LocalDateTime endTime = time.plusHours(24);List<CountVo> list = reservationMapper.getCountByTime(time, endTime);return reservationMapper.getCountByTime(time,endTime);}/*** 查找所有预约* @param mobile 预约人手机号* @param time 预约时间*/@Overridepublic List<ReservationVo> findAll(String mobile, LocalDateTime time) {LocalDateTime endTime = time.plusHours(24); // 计算24小时后的时间Long userId = UserThreadLocal.getUserId();List<Reservation> reservations = reservationMapper.findAll(userId, mobile, time, endTime); // 根据mobile和时间范围查询预约return convertToVOList(reservations);}private List<ReservationVo> convertToVOList(List<Reservation> reservations){return reservations.stream().map(this::convertToVO).collect(Collectors.toList());}/*** 新增预约信息* @param reservationDto*/@Overridepublic void addReservation(ReservationDto reservationDto) {// 1. 查看数据库的表// 获取当前的useridLong userId = UserThreadLocal.getUserId();// 判断今天取消的次数是否大于3次Long cancelledCount = cancelledCount(userId);// 如果大于3次则不进行预约if(cancelledCount >=3 ){throw new RuntimeException(String.valueOf(BasicEnum.RESERVATION_CANCEL_COUNT_UPPER_LIMIT));}// 进行预约Reservation reservation = new Reservation();BeanUtils.copyProperties(reservationDto,reservation);// 预约状态,0:待报道reservation.setStatus(ReservationStatus.PENDING.getOrdinal());reservation.setCreateBy(userId);try {reservationMapper.insert(reservation);}catch (Exception e){log.info(e + "");throw new RuntimeException(String.valueOf(BasicEnum.TIME_ALREADY_RESERVATED_BY_PHONE));}}/*** 分页查询预约* @param pageNum* @param pageSize* @param name* @param phone* @param status* @param type* @param startTime* @param endTime* @return*/@Overridepublic PageResponse<ReservationVo> findByPage(int pageNum, int pageSize, String name, String phone, Integer status, Integer type, LocalDateTime startTime, LocalDateTime endTime) {PageHelper.startPage(pageNum,pageSize);Long userId = UserThreadLocal.getUserId();Page<Reservation> page = reservationMapper.findByPage(pageNum,pageSize,name, phone, status, type, userId, startTime, endTime);return PageResponse.of(page,ReservationVo.class);}/*** 取消预约* @param id*/@Overridepublic void cancelledById(Long id) {Reservation reservation = reservationMapper.findById(id);if(ObjectUtil.isNotEmpty(reservation)){// 2:取消reservation.setStatus(ReservationStatus.CANCELED.getOrdinal());reservationMapper.update(reservation);}}/*** 更新预约*/@Overridepublic void update(Long id, ReservationDto dto) {Reservation reservation = reservationMapper.findById(id);if (reservation != null) {BeanUtils.copyProperties(dto, reservation);reservation.setId(id);reservation.setUpdateTime(LocalDateTime.now());reservationMapper.update(reservation);}}/*** 将Reservation转换为ReservationVO*/private ReservationVo convertToVO(Reservation reservation) {return BeanUtil.toBean(reservation, ReservationVo.class);}/*** 将时间戳转换为字符串*/private String convertTimeToStr(Long time) {return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(time));}/*** 如果预约未完成,则将预约状态更新为过期*/@Overridepublic void updateVisitReservationStatusToExpiredIfNotCompleted(Long id) {Reservation visitReservation = reservationMapper.findById(id);// 判断是否 已经完成 || 已取消 -- > 是就直接返回if (visitReservation.getStatus().equals(ReservationStatus.COMPLETED.getOrdinal())|| visitReservation.getStatus().equals(ReservationStatus.CANCELED.getOrdinal()) ) {return;}LocalDateTime reservationTime = visitReservation.getTime();LocalDateTime currentTime = LocalDateTime.now();if (currentTime.isAfter(reservationTime.plusHours(1))) {visitReservation.setStatus(ReservationStatus.EXPIRED.getOrdinal());reservationMapper.update(visitReservation);}}/*** 根据id查找预约*/@Overridepublic ReservationVo findById(Long id) {Reservation reservation = reservationMapper.findById(id);if (reservation != null) {return convertToVO(reservation);}return null;}/*** 来访* @param id ID* @param time 时间*/@Overridepublic void visit(Long id, Long time) {Reservation reservation = reservationMapper.findById(id);if (reservation != null) {reservation.setStatus(ReservationStatus.COMPLETED.getOrdinal());reservationMapper.update(reservation);VisitDto visitDto = BeanUtil.toBean(reservation, VisitDto.class);visitDto.setTime(LocalDateTimeUtil.of(time));visitService.add(visitDto);}}@Overridepublic void updateReservationStatus(LocalDateTime now) {reservationMapper.updateReservationStatus(now);}}
package com.zzyl.mapper;import com.github.pagehelper.Page;
import com.zzyl.entity.Reservation;
import com.zzyl.vo.CountVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;import java.time.LocalDateTime;
import java.util.List;@Mapper
public interface ReservationMapper {void update(Reservation reservation);void insert(Reservation reservation);int deleteById(Long id);Reservation findById(@Param("id") Long id);List<CountVo> getCountByTime(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);List<Reservation> findAll(@Param("createBy") Long userId, @Param("mobile") String mobile, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);int countReservationsWithinTimeRange(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime, @Param("createBy") Long createBy, @Param("status") Integer status);Page<Reservation> findByPage(@Param("page") int startIndex, @Param("pageSize") int pageSize, @Param("name") String name, @Param("mobile") String mobile, @Param("status") Integer status, @Param("type") Integer type, @Param("createBy") Long userId, @Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);Long getcancelledCount(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime, @Param("userId") Long userId);@Update("update reservation set status = 3 where status = 0 and time <= #{minusDays}")void updateReservationStatus(LocalDateTime minusDays);}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zzyl.mapper.ReservationMapper"><resultMap id="reservationMap" type="com.zzyl.entity.Reservation"><id column="id" property="id"/><result column="name" property="name"/><result column="mobile" property="mobile"/><result column="time" property="time"/><result column="visitor" property="visitor"/><result column="type" property="type"/><result column="status" property="status"/><result column="create_by" property="createBy"/><result column="update_by" property="updateBy"/><result column="remark" property="remark"/><result column="create_time" property="createTime"/><result column="update_time" property="updateTime"/><result column="creator" property="creator"/></resultMap><insert id="insert" parameterType="com.zzyl.entity.Reservation">insert into reservation(name, mobile, time, visitor, type, status, create_by, remark, create_time)values (#{name}, #{mobile}, #{time}, #{visitor}, #{type}, #{status}, #{createBy}, #{remark}, #{createTime})</insert><update id="update">update reservationset name = #{name},mobile = #{mobile},time = #{time},visitor = #{visitor},type = #{type},status = #{status},update_time = #{updateTime},update_by = #{updateBy}where id = #{id}</update><delete id="deleteById" parameterType="java.lang.Long">deletefrom reservationwhere id = #{id}</delete><select id="findByPage" parameterType="java.util.Map" resultType="com.zzyl.entity.Reservation">select r.id, r.name, r.mobile, r.time, r.visitor, r.type, r.status, r.create_by, r.remark, r.create_time, s.nameas creator from reservation rLEFT JOIN member s ON s.id = r.create_by<where><if test="name != null and name != ''">and r.name like concat('%',#{name},'%')</if><if test="mobile != null and mobole != ''">and r.mobile = #{mobile}</if><if test="status != null">and r.status = #{status,jdbcType=INTEGER}</if><if test="createBy != null">and r.create_by = #{createBy}</if><if test="startTime != null and endTime != null">and r.time BETWEEN #{startTime} and #{endTime}</if></where>order by create_time desc</select><select id="getCountByTime" resultType="com.zzyl.vo.CountVo">SELECT time, 6 - COUNT(*) AS countFROM reservationWHERE `time` BETWEEN #{startTime}AND #{endTime}and status != 2GROUP BY time</select><select id="findAll" resultMap="reservationMap">select * from reservationWHERE time BETWEEN #{startTime} AND #{endTime}<if test="mobile != null and mobile != ''">and mobile = #{mobile}</if><if test="createBy != null">AND create_by = #{createBy}</if>order by create_time desc</select><select id="getcancelledCount" resultType="java.lang.Long">select count(*) from reservationwhere update_time between #{startTime} and #{endTime}and status = 2and update_by = #{userId}</select><select id="findById" resultType="com.zzyl.entity.Reservation">select * from reservationwhere id = #{id}</select><select id="countReservationsWithinTimeRange" resultType="java.lang.Integer">ELECT COUNT(*) FROM reservationWHERE time BETWEEN #{startTime} AND #{endTime}<if test="createBy != null">AND create_by = #{createBy}</if><if test="status != null">and status = #{status, jdbcType=INTEGER}</if></select></mapper>
相关文章:
预约功能的知识整理
前置知识 如果项目为小程序的开发项目中: 我们确定数据库中有的字段有: 预约人姓名、手机号、家人名称、预约时间 根据我们的经定一表必须要有的6个字段: 主键、创建时间、修改时间、创建人、修改人、备注 使用我们现在有的字段为: 主键…...
Linux的常用操作-02
一:Linux的系统目录结构 /bin bin是ary的缩写,这个目录存放着最经常用的命令 /boot:这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件。 /dev:dev是Device(设备)的缩写,该目录下存放的是Lin…...
Android Studio 连接手机进行调试
总所周知,Android Studio里的虚拟手机下载后又大又难用。不如直接连手机用。本篇文章主要内容为Android Studio怎么连接手机进行程序调试。 1. 在AndroidSDK中下载google USB Driver: 2. 连接手机: 进入电脑设备管理器界面。并点开便携设备,…...
Vue3项目创建及相关配置
Vue是一种用于构建用户界面的JavaScript框架。它采用了一种称为MVVM(Model-View-ViewModel)的架构模式。 MVVM是一种将用户界面与业务逻辑和数据分离的设计模式。它包括三个部分: Model(模型):表示应用程序…...
【Python】Python中一些有趣的用法
Python是一种非常灵活和强大的编程语言,它有很多有趣的用法,以下是一些例子: 一行代码实现FizzBuzz: print(\n.join([FizzBuzz[i%3*4:i%5*8:-1] or str(i) for i in range(1, 101)]))使用列表推导式生成斐波那契数列: …...
RCE复现问题和研究
目录 先了解一些常见的知识点 PHP常见命令执行函数 call_user_func eval() call_user_func_array array_filter 实战演练(RCE)PHP Eval函数参数限制在16个字符的情况下 ,如何拿到Webshell? 1、长度…...
MySQL中的索引——适合创建索引的情况
1.适合创建索引的情况 1、字段的数值有唯一性的限制 2、频繁作为 WHERE 查询条件的字段 某个字段在 SELECT 语句的 WHERE 条件中经常被使用到,那么就需要给这个字段创建索引了。尤其是在数据量大的情况下,创建普通索引就可以大幅提升数据查询的效率。 …...
5款在线伪原创改写软件,智能改写文章效果好
在这个信息爆炸的时代,内容创作变得愈发重要,而对于创作者来说,有时需要一些得力的伪原创改写工具来辅助我们更好地改写出高质量的内容。今天我要和大家分享5款令人惊喜的在线伪原创改写软件,它们以出色的智能改写效果,…...
opencv-python图像增强四:多曝光融合(方法一)
文章目录 一、简介:二、多曝光融合方案:三、算法实现步骤3.1 读取图像与曝光时间:3.2 计算响应曲线并合并3.3 色调映射 四:整体代码实现五:效果 一、简介: 在摄影和计算机视觉领域,高动态范围&…...
Qt 实战(9)窗体 | 9.2、QDialog
文章目录 一、QDialog1、基本概念2、常用特性2.1、模态与非模态2.2、数据交互 3、总结 前言: Qt框架中的QDialog类是一个功能强大且灵活的对话框控件,广泛应用于各种GUI(图形用户界面)应用程序中,用于处理用户输入、消…...
Spring 事务机制
1. 引言 1.1 什么是事务 事务是由用户定义的一系列操作序列所组成的最小工作单元;这些操作要么全部完成,要么全部不完成,是一个不可分割的工作单元。常见于数据库中的并发控制和数据一致性处理场景。 1.2 事务的特性 事务具有以下特性&am…...
Android 13 GMS 内置壁纸
如图,原生系统上,设备上的壁纸 显示系统内置壁纸。如果没有添加内置壁纸,就显示默认的壁纸。点击进去就是预览页面 扩展下,默认壁纸在 frameworks/base/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png frameworks/b…...
【LeetCode】234. 回文链表
回文链表 题目描述: 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:head [1,2,2,1] 输出:true示例 2&#…...
零基础学会机器学习,到底要多久?
这两天啊,有不少朋友和我说,想学机器学习,但是之前没有基础,不知道能不能学得会。 首先说结论,只要坚持,就能学会,但是一定不能三天打鱼两天晒网,要持之以恒,至少每隔两…...
视频汇聚/安防监控综合平台EasyCVR接入海康私有协议EHOME显示失败是什么原因?
安防监控/视频综合管理平台/视频集中存储/磁盘阵列EasyCVR视频汇聚平台,支持多种视频格式和编码方式(H.264/H.265),能够轻松对接各类前端监控设备,实现视频流的统一接入与集中管理。安防监控EasyCVR平台支持多种流媒体…...
Qt解析XML
背景 本来想解析VS的项目配置文件(*.vcxproj),配合cppclean来发现多余的#incldue。 结果发现低估了难度,VS会间接引入许多目录。 略有不甘,暂且作为一个解析XML文件的示例。 代码 VSProjectParser.h #include <QVector> #include…...
PwnLab: init-文件包含、shell反弹、提权--靶机渗透思路讲解
Vulnhub靶机链接回【PwnLab】 首页有一个登录框 image-20240807124822770 他没有验证码,我们试试暴力破解 image-20240807122743025 开始爆破了,全部失败,哈哈哈 image-20240807122851001 nmap全端口扫描试试 image-20240807131408315 有…...
OpenCV—二值化Threshold()、adaptiveThreshold()
cv2.threshold() c:double cv::threshold ( InputArray src, OutputArray dst, double thresh, double maxval, int type ) (注:源图片, 目标图, 阈值, 填充色, 阈值类型) python:cv.threshold(src,thresh, maxval, type[, dst]) src:源图片…...
第二天:java面向对象编程(OOP)
第二天:java面向对象编程(OOP) 1. 深入理解OOP四大特性 封装(Encapsulation):学习如何将数据(属性)和操作数据的方法(行为)组合成一个独立的单元࿰…...
Selenium + Python 自动化测试07(滑块的操作方法)
我们的目标是:按照这一套资料学习下来,大家可以独立完成自动化测试的任务。 本篇文章主要讲述如何操作滑块。 目前很多系统登录或者注册的页面都有滑块相关的验证,selenium 中对滑块的基本操作采用了元素的拖曳的方式。需要用到Actiochains模…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
