苍穹外卖Day01

目录

管理端开发

准备工作:

前端

后端

数据库

启动后端服务运行

员工相关接口开发

分页查询员工信息

禁用员工账号

修改员工信息

新增员工

Gitee管理代码

分类接口开发


管理端开发

准备工作

前端

双击nginx.exe运行前端项目

后端

接口文档:使用工具Apifox导入api接口文档,这里给的数据是从YAPI导出的

导入初始化工程:common(公共功能模块)、pojo(处理数据的接收、返回,就是为了更好封装数据)、server(处理接口)

加载maven依赖

yml配置:mysql服务地址、密码

JDK版本: 11

数据库

导入sky.sql脚本

启动后端服务运行

员工相关接口开发

分页查询员工信息

@Override
    public Result<PageResult> pageEmployee(String name, Integer page, Integer pageSize) {
        // 开启分页查询
        PageHelper.startPage(page, pageSize);
        // 动态条件查询
        Page<Employee> employeeList = employeeMapper.pageEmployee(name);
        PageResult pageResult = new PageResult(employeeList.getTotal(), employeeList.getResult());
        return Result.success(pageResult);
    }

使用PageHelper工具类开启分页查询,PageHelper会在执行sql前进行拦截并且拼接分页sql,然后进行查询时返回数据类型为Page<>,这样返回的该对象会包含总记录数、总页数、当前页码、每页记录数等分页信息。

禁用员工账号

修改员工信息

public void UpdateStatus(Integer status, Long id) {
        Employee employee = Employee
                    .builder()
                    .id(id).status(status)
                    .build();
        employeeMapper.updateStatus(employee);
    }

虽然可以直接传入禁用和员工id进行禁用,可将其封装为Entity类再进行修改,这样两个Service就可以调用同一个mapper来完成更新。

新增员工

@Override
    public void save(EmployeeDTO employeeDTO) {
        Employee employee = new Employee();
        BeanUtils.copyProperties(employeeDTO, employee);
        String password = DigestUtils.md5DigestAsHex(DEFAULT_PASSWORD.getBytes());// 默认密码进行md5加密
        employee.setPassword(password); 
        employee.setStatus(StatusConstant.ENABLE);
        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());
        employee.setCreateUser(BaseContext.getCurrentId());
        employee.setUpdateUser(BaseContext.getCurrentId());
        employeeMapper.save(employee);
    }

可以看到这里有大量重复冗余的代码,就是将当前时间和用户id信息传入进employee。并且在以后的更新和新增操作还要重复写这些代码

解决:AOP

// 枚举类
public enum OperationType {
​
    /**
     * 更新操作
     */
    UPDATE,
​
    /**
     * 插入操作
     */
    INSERT
​
}
​
//第一步:自定义注解,用于标识需要进行公共字段填充的方法
//元注解,用于指定被注解的元素类型, 这里指方法
@Target(ElementType.METHOD)
//在运行时仍然保留,通过反射机制在运行时获取注解信息。意味着在程序运行过程中,可以使用 Java 的反射 API 来检查某个方法是否被 AutoFill 注解标记,以及获取注解中定义的属性值。
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    //定义需要自动填充的字段, 数据库操作的类型 update 、insert
    OperationType value();
}
​
// 第二步:自定义切面类,用于拦截加入自定义注解的方法
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
​
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut() {
    }
​
    // 在 autoFillPointCut 所定义的切入点的目标方法执行前执行
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) {
        log.info("开始进行数据填充.....");
        // 获取到当前被拦截的方法上的数据库操作类型
        MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名对象
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class); // 获得方法上的注解对象
        OperationType operationType = autoFill.value(); // 获得数据库操作类型
​
        // 获取到当前被拦截的方法参数 实体对象
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0) {
            return;
        }
        Object entity = args[0];
​
        // 准备赋值的数据
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();
​
        try {
            if (operationType == OperationType.INSERT) {
                // 为实体对象各个属性赋值
                invokeSetMethod(entity, AutoFillConstant.SET_CREATE_TIME, now);
                invokeSetMethod(entity, AutoFillConstant.SET_CREATE_USER, currentId);
                invokeSetMethod(entity, AutoFillConstant.SET_UPDATE_TIME, now);
                invokeSetMethod(entity, AutoFillConstant.SET_UPDATE_USER, currentId);
            } else if (operationType == OperationType.UPDATE) {
                // 为实体对象各个属性赋值
                invokeSetMethod(entity, AutoFillConstant.SET_UPDATE_TIME, now);
                invokeSetMethod(entity, AutoFillConstant.SET_UPDATE_USER, currentId);
            }
        } catch (Exception e) {
            log.error("自动填充数据时发生异常", e);
        }
    }
​
    private void invokeSetMethod(Object entity, String methodName, Object value) throws Exception {
        Method method = entity.getClass().getDeclaredMethod(methodName, value.getClass());
        method.invoke(entity, value);
    }
}
​
// 第三步:在Mapper的方法加上自定义注解
@AutoFill(value = OperationType.UPDATE)
void updateStatus(Employee employee);
​
@AutoFill(value = OperationType.INSERT)
void save(Employee employee);

Gitee管理代码

远程仓库

Gitee 官网(https://gitee.com/),点右上角 “+” 选 “新建仓库”,复制 HTTPS 或 SSH 地址。

本地仓库

idea点击 “VCS”,选 “Import into Version Control”→“Create Git Repository”,选项目根目录确认。

关联

点击 “VCS”→“Git”→“Remotes”,点 “+”,“Name” 填 “origin”,“URL” 粘贴 Gitee 复制的地址,测试连接后确认。

提交到本地仓库And推送到远程仓库

提交(Commit) 、推送(Push)

分类接口开发

代码功能基本和员工管理类似,不做概述

### 苍穹外卖 Day 功能配置与时间处理 在苍穹外卖项目的学习过程中,关于日期或时间设置的功能配置是一个常见的关注点。以下是对此主题的详细解析: #### 1. **时间戳的应用** 在软件开发中,时间戳通常用于记录事件发生的具体时刻。对于苍穹外卖这样的应用来说,订单创建时间、配送预计完成时间等功能都需要依赖于精确的时间管理[^1]。 ```python import time # 获取当前时间戳 current_timestamp = int(time.time()) print(f"Current Timestamp: {current_timestamp}") ``` 通过上述代码可以获取到当前的时间戳,并将其存储至数据库以便后续使用。这种做法能够有效减少因时区差异带来的误差问题[^2]。 #### 2. **定时任务调度** 为了实现某些特定时间段内的操作自动化执行(比如每日凌晨清理过期数据),可以通过 `APScheduler` 库来设定周期性的后台作业计划表[^3]。 ```python from apscheduler.schedulers.background import BackgroundScheduler def clean_expired_data(): print("Cleaning expired data...") scheduler = BackgroundScheduler() scheduler.add_job(clean_expired_data, 'cron', hour=0, minute=0) # 设置每天零点运行一次 scheduler.start() try: while True: time.sleep(2) except (KeyboardInterrupt, SystemExit): scheduler.shutdown() ``` 此段脚本展示了如何利用 APScheduler 来安排每晚午夜自动清除旧资料的任务实例。 #### 3. **前端显示本地化时间** 当涉及到跨区域用户的交互界面设计时,则需考虑不同地区的用户看到的是他们所在位置对应的标准时间而非统一服务器端时间。因此,在返回给客户端的数据包里附带原始 UTC 时间的同时也要提供转换方法让浏览器自行调整成适合访问者的当地时间格式。 ```javascript function convertToLocalTime(utcDate){ const localDate = new Date(utcDate); return `${localDate.toLocaleDateString()} ${localDate.toLocaleTimeString()}`; } console.log(convertToLocalTime('2024-01-01T00:00:00Z')); ``` 以上 JavaScript 函数接受一个 ISO 字符串形式表示的世界协调世界时作为输入参数并输出经过变换后的当地实际可见版本字符串结果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值