学习: 尚硅谷Java项目之小谷充电宝(3)

七、权限管理,日志,代码生成

若依-权限控制

完善系统权限功能

添加按钮权限数据

添加按钮权限

添加注解
复制代码
@RequiresPermissions("")

CabinetTypeController.java

java 复制代码
package com.share.device.controller;

import com.share.common.core.web.controller.BaseController;
import com.share.common.core.web.domain.AjaxResult;
import com.share.common.core.web.page.TableDataInfo;
import com.share.common.security.annotation.RequiresPermissions;
import com.share.device.domain.CabinetType;
import com.share.device.service.ICabinetTypeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@Tag(name = "柜机类型接口管理")
@RestController
@RequestMapping("/cabinetType")
public class CabinetTypeController extends BaseController {
    @Autowired
    private ICabinetTypeService cabinetTypeService;

    /**
     * 查询柜机类型列表
     */
    @Operation(summary = "查询柜机类型列表")
    @RequiresPermissions("device:cabinetType:list")
    @GetMapping("/list")
    public TableDataInfo list(CabinetType cabinetType) {
        //封装分页参数数据
        startPage();
        //调用service查询数据库
        List<CabinetType> list = cabinetTypeService.selectCabinetTypeList(cabinetType);
        TableDataInfo dataTable = getDataTable(list);
        return dataTable;
    }

    /**
     * 根据id查询详情
     */
    @Operation(summary = "获取柜机类型详细信息")
    @RequiresPermissions("device:cabinetType:query")
    @GetMapping(value = "/{id}")
    public AjaxResult getCabinetType(@PathVariable Long id) {
        CabinetType cabinetType = cabinetTypeService.getById(id);
        AjaxResult ajaxResult = success(cabinetType);
        return ajaxResult;
    }


    /**
     * 新增柜机类型
     */
    @Operation(summary = "新增柜机类型")
    @RequiresPermissions("device:cabinetType:add")
    @PostMapping
    public AjaxResult add(@RequestBody CabinetType cabinetType) {
        boolean is_Success = cabinetTypeService.save(cabinetType);
        AjaxResult ajaxResult = toAjax(is_Success);
        return ajaxResult;
    }

    /**
     * 修改柜机类型
     */
    @Operation(summary = "修改柜机类型")
    @RequiresPermissions("device:cabinetType:edit")
    @PutMapping
    public AjaxResult edit(@RequestBody CabinetType cabinetType) {
        boolean is_Success = cabinetTypeService.updateById(cabinetType);
        AjaxResult ajaxResult = toAjax(is_Success);
        return ajaxResult;
    }

    /**
     * 删除柜机类型
     * 根据id删除某个数据,或者根据多个id删除多个数据
     */
    @Operation(summary = "删除柜机类型")
    @RequiresPermissions("device:cabinetType:remove")
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        boolean is_Success = cabinetTypeService.removeByIds(Arrays.asList(ids));
        AjaxResult ajaxResult = toAjax(is_Success);
        return ajaxResult;
    }


    /**
     * 查询全部柜机类型列表
     *
     * @return
     */
    @Operation(summary = "查询全部柜机类型列表")
    @GetMapping("/getCabinetTypeList")
    public AjaxResult getCabinetTypeList() {
        return success(cabinetTypeService.list());
    }

}
vue页面按钮控制
javascript 复制代码
 v-hasPermi="['device:cabinetType:add']"
通过管理系统进行菜单访问控制

新建角色

新建用户

登录

若依-系统日志

完善系统日志

java 复制代码
/**
     * 新增柜机类型
     */
    @Operation(summary = "新增柜机类型")
    @RequiresPermissions("device:cabinetType:add")
    @Log(title = "柜机类型", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody CabinetType cabinetType) {
        boolean is_Success = cabinetTypeService.save(cabinetType);
        AjaxResult ajaxResult = toAjax(is_Success);
        return ajaxResult;
    }

    /**
     * 修改柜机类型
     */
    @Operation(summary = "修改柜机类型")
    @RequiresPermissions("device:cabinetType:edit")
    @Log(title = "柜机类型", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody CabinetType cabinetType) {
        boolean is_Success = cabinetTypeService.updateById(cabinetType);
        AjaxResult ajaxResult = toAjax(is_Success);
        return ajaxResult;
    }

    /**
     * 删除柜机类型
     * 根据id删除某个数据,或者根据多个id删除多个数据
     */
    @Operation(summary = "删除柜机类型")
    @RequiresPermissions("device:cabinetType:remove")
    @Log(title = "柜机类型", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        boolean is_Success = cabinetTypeService.removeByIds(Arrays.asList(ids));
        AjaxResult ajaxResult = toAjax(is_Success);
        return ajaxResult;
    }

若依-代码生成

会员管理模块

需要对哪个数据库表生成代码,那么就连接哪个数据库

share.user

进入系统工具-代码生成页面,勾选user_info表并生成

预览

会员管理

新建share-user模块

pom.xml

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.share</groupId>
        <artifactId>share-modules</artifactId>
        <version>3.6.3</version>
    </parent>

    <artifactId>share-user</artifactId>
    <description>
        share-user会员模块
    </description>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- SpringCloud Alibaba Nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- SpringCloud Alibaba Nacos Config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <!-- SpringCloud Alibaba Sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

        <!-- SpringBoot Actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!-- Mysql Connector -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>

        <!-- RuoYi Common DataSource -->
        <!--        <dependency>-->
        <!--            <groupId>com.share</groupId>-->
        <!--            <artifactId>share-common-datasource</artifactId>-->
        <!--        </dependency>-->

        <!-- RuoYi Common DataScope -->
        <dependency>
            <groupId>com.share</groupId>
            <artifactId>share-common-datascope</artifactId>
        </dependency>

        <!-- RuoYi Common Log -->
        <dependency>
            <groupId>com.share</groupId>
            <artifactId>share-common-log</artifactId>
        </dependency>

    </dependencies>
    
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

banner.txt、bootstrap.yml、logback.xml

share-user-dev.yml

启动类ShareUserApplication

java 复制代码
package com.share.user;

import com.share.common.security.annotation.EnableCustomConfig;
import com.share.common.security.annotation.EnableRyFeignClients;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableCustomConfig
@EnableRyFeignClients
@SpringBootApplication
public class ShareUserApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(ShareUserApplication.class, args);
        System.out.println("(♥◠‿◠)ノ゙  会员模块启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
                " | ( ' )  |       \\  _. /  '       \n" +
                " |(_ o _) /        _( )_ .'         \n" +
                " | (_,_).' __  ___(_ o _)'          \n" +
                " |  |\\ \\  |  ||   |(_,_)'         \n" +
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
    }
}

share-gateway-dev.yml

生成代码main文件夹放入share-user模块,生成代码vue文件夹放入share-ui模块

拷贝代码生成的userInfoMenu.sql文件中的sql

java 复制代码
-- 菜单 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('用户', '2013', '1', 'userInfo', 'user/userInfo/index', 1, 0, 'C', '0', '0', 'device:userInfo:list', '#', 'admin', sysdate(), '', null, '用户菜单');

-- 按钮父菜单ID
SELECT @parentId := LAST_INSERT_ID();

-- 按钮 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('用户查询', @parentId, '1',  '#', '', 1, 0, 'F', '0', '0', 'device:userInfo:query',        '#', 'admin', sysdate(), '', null, '');

insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('用户新增', @parentId, '2',  '#', '', 1, 0, 'F', '0', '0', 'device:userInfo:add',          '#', 'admin', sysdate(), '', null, '');

insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('用户修改', @parentId, '3',  '#', '', 1, 0, 'F', '0', '0', 'device:userInfo:edit',         '#', 'admin', sysdate(), '', null, '');

insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('用户删除', @parentId, '4',  '#', '', 1, 0, 'F', '0', '0', 'device:userInfo:remove',       '#', 'admin', sysdate(), '', null, '');

insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('用户导出', @parentId, '5',  '#', '', 1, 0, 'F', '0', '0', 'device:userInfo:export',       '#', 'admin', sysdate(), '', null, '');

添加动态菜单

八、微信授权登录

用户登录

远程接口开发

pom.xml

微信Java开发工具包

java 复制代码
<dependency>
    <groupId>com.github.binarywang</groupId>
    <artifactId>weixin-java-miniapp</artifactId>
</dependency>
share-user-dev.yml
java 复制代码
wx:
  miniapp:
    appId: wxcc651fcbab275e33
    secret: 5f353399a2eae7ff6ceda383e924c5f6
WxMaProperties
java 复制代码
package com.share.user.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxMaProperties {
    private String appId;
    private String secret;
}
WxMaConfig
java 复制代码
package com.share.user.config;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class WxMaConfig {
    @Autowired
    private WxMaProperties wxMaProperties;

    @Bean
    public WxMaService wxMaService() {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(wxMaProperties.getAppId());
        config.setSecret(wxMaProperties.getSecret());

        WxMaService service = new WxMaServiceImpl();
        service.setWxMaConfig(config);
        return service;
    }
}
UpdateUserLogin
java 复制代码
package com.share.user.api.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.util.Date;

@Data
public class UpdateUserLogin {
    private Long userId;

    /** 最后一次登录ip */
    private String lastLoginIp;

    /** 最后一次登录时间 */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date lastLoginTime;
}
UserInfoApiController
java 复制代码
package com.share.user.api;

import com.share.common.core.domain.R;
import com.share.common.core.web.controller.BaseController;
import com.share.common.security.annotation.InnerAuth;
import com.share.user.api.domain.UpdateUserLogin;
import com.share.user.domain.UserInfo;
import com.share.user.service.IUserInfoService;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/userInfo")
public class UserInfoApiController extends BaseController {
    @Autowired
    private IUserInfoService userInfoService;

   
}

小程序授权登录

UserInfoApiController.java

java 复制代码
    @Operation(summary = "小程序授权登录")
    @GetMapping("/wxLogin/{code}")
    public R<UserInfo> wxLogin(@PathVariable String code) {
        return R.ok(userInfoService.wxLogin(code));
    }

在'UserlnfoService'中创建方法'wxLogin

java 复制代码
    //微信授权登录-远程调用
    UserInfo wxLogin(String code);

实现方法

java 复制代码
package com.share.user.service.impl;

import java.util.List;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.share.user.mapper.UserInfoMapper;
import com.share.user.domain.UserInfo;
import com.share.user.service.IUserInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 用户Service业务层处理
 *
 * @author atguigu
 * @date 2026-03-09
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements IUserInfoService {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private WxMaService wxMaService;

    /**
     * 查询用户列表
     *
     * @param userInfo 用户
     * @return 用户
     */
    @Override
    public List<UserInfo> selectUserInfoList(UserInfo userInfo) {
        return userInfoMapper.selectUserInfoList(userInfo);
    }

    @Override
    public UserInfo wxLogin(String code) {

        //code+微信公众平台id+秘钥,返回openid
        try {
            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            String openId = sessionInfo.getOpenid();
            //openid查询数据库表
            LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserInfo::getWxOpenId, openId);
            //添加用户信息到数据库
            UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);
            //判断
            if (userInfo == null) {
                //如果表里面没有openid值,表示第一次登录
                //添加用户信息到数据库表
                userInfo = new UserInfo();
                userInfo.setNickname(String.valueOf(System.currentTimeMillis()));
                userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
                userInfo.setWxOpenId(openId);
                userInfoMapper.insert(userInfo);
            }
            //返回userInfo用户信息
            return userInfo;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

    }

}

更新用户登录信息

openFeign接口定义

操作模块:share-api-user

com/share/common/core/constant/ServiceNameConstants.java

java 复制代码
    /**
     * 用户服务
     */
    public static final String SHARE_USER = "share-user";
RemoteUserService
java 复制代码
package com.share.user.api;

import com.share.user.domain.UserInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import com.share.common.core.constant.ServiceNameConstants;
import com.share.common.core.domain.R;
import com.share.system.api.factory.RemoteUserFallbackFactory;

/**
 * 用户服务
 *
 * @author share
 */
@FeignClient(contextId = "remoteUserInfoService",
        value = ServiceNameConstants.SHARE_USER,
        fallbackFactory = RemoteUserFallbackFactory.class)
public interface RemoteUserService {
    }
RemoteUserInfoFallbackFactory
java 复制代码
package com.share.user.factory;

import com.share.common.core.exception.ServiceException;
import com.share.system.api.RemoteUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

/**
 * 用户服务降级处理
 *
 * @author share
 */
@Component
public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserService> {
    private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class);

    @Override
    public RemoteUserService create(Throwable throwable) {
        log.error("用户服务调用失败:{}", throwable.getMessage());
        throw new ServiceException("调用出现错误");

    }
}

share-user\pom.xml

java 复制代码
<dependency>
    <groupId>com.share</groupId>
    <artifactId>share-api-user</artifactId>
    <version>3.6.3</version>
</dependency>
META-INF
RemoteUserService
java 复制代码
    /**
     *
     *
     * @param code 请求来源
     * @return 结果
     */
    @GetMapping("/userInfo/wxLogin/{code}")
    public R<UserInfo> wxLogin(@PathVariable("code") String code);

开发登录业务接口

操作模块:share-auth

H5TokenController
java 复制代码
package com.share.auth.controller;


import org.springframework.web.bind.annotation.RestController;

@RestController
public class H5TokenController {

}
pom.xml
java 复制代码
<dependency>
    <groupId>com.share</groupId>
    <artifactId>share-api-user</artifactId>
    <version>3.6.3</version>
</dependency>
H5LoginService
java 复制代码
package com.share.auth.service;

import org.springframework.stereotype.Component;

@Component
public class H5LoginService {
}
H5TokenController
java 复制代码
package com.share.auth.controller;


import com.share.auth.service.H5LoginService;
import com.share.common.core.domain.R;
import com.share.common.security.service.TokenService;
import com.share.system.api.model.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;


/**
 * H5TokenController类
 * 处理H5端登录相关的请求
 */
@RestController
public class H5TokenController {
    @Autowired
    private H5LoginService h5LoginService;

    @Autowired
    private TokenService tokenService;

    /**
     * 处理H5端登录请求
     *
     * @param code 登录授权码
     * @return 返回包含登录token的响应结果
     */
    @GetMapping("/h5/login/{code}")
    public R<?> login(@PathVariable String code) {
        // 用户登录,使用授权码获取用户信息
        LoginUser userInfo = h5LoginService.login(code);
        // 获取登录token并返回成功响应
        return R.ok(tokenService.createToken(userInfo));
    }

}

在'H5LoginService'中创建方法"login'

java 复制代码
package com.share.auth.service;

import com.share.common.core.domain.R;
import com.share.common.core.exception.ServiceException;
import com.share.common.core.utils.StringUtils;
import com.share.system.api.model.LoginUser;
import com.share.user.api.RemoteUserService;
import com.share.user.domain.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class H5LoginService {
    @Autowired
    private RemoteUserService remoteUserService;


    /**
     * 登录
     */
    public LoginUser login(String code) {
        //判断code值是否为空
        if (StringUtils.isAnyBlank(code)) {

            throw new ServiceException("数据为空");
        }
        //进行远程调用完成登录,返回userInfo对象
        R<UserInfo> userResult = remoteUserService.wxLogin(code);
        UserInfo userInfo = userResult.getData();
        //判断返回的userInfo是否为空
        if (userInfo == null) {
            throw new ServiceException("数据为空");
        }
        String status = userInfo.getStatus();
        if ("2".equals(status)){
            throw new ServiceException("账号被禁用");
        }
        //封装数据到LoginUser对象里面
        LoginUser loginUser = new LoginUser();
        loginUser.setUserid(userInfo.getId());
        loginUser.setUsername(userInfo.getWxOpenId());
        loginUser.setStatus(userInfo.getStatus() + "");
        //返回数据
        return loginUser;
    }
}
share-gateway-dev.yml

排除登录认证

根据token获取用户基本信息

实体类UserVo

操作模块:share-api-user

java 复制代码
package com.share.user.domain;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

@Data
@Schema(description = "用户类")
public class UserVo {
    @Schema(description = "昵称")
    private String nickname;

    @Schema(description = "头像")
    private String avatar;

    @Schema(description = "微信open id")
    private String wxOpenId;

    @Schema(description = "押金状态(0:未验证 1:免押金 2:已交押金)")
    private String depositStatus;
}
UserInfoApiController

操作模块:share-user

java 复制代码
@Operation(summary = "获取当前登录用户信息")
@RequiresLogin
@GetMapping("/getLoginUserInfo")
public AjaxResult getLoginUserInfo(HttpServletRequest request) {
    Long userId = SecurityContextHolder.getUserId();
    UserInfo userInfo = userInfoService.getById(userId);
    UserVo userInfoVo = new UserVo();
    BeanUtils.copyProperties(userInfo, userInfoVo);
    return success(userInfoVo);
}

启动

  1. 小程序请求 → /auth/h5/login/{code}
  2. H5LoginService.login() 调用 RemoteUserService.wxLogin(code)
  3. 远程调用 → share-user 服务的 UserInfoApiController.wxLogin(code)
  4. UserInfoServiceImpl.wxLogin() 中使用 WxMaService 通过 code 换取 openid
  5. 用 openid 查询数据库,不存在则创建新用户
  6. 返回 UserInfo
相关推荐
头疼的程序员2 小时前
计算机网络:自顶向下方法(第七版)第三章 学习分享(二)
网络·学习·计算机网络
wzqllwy2 小时前
8 大经典排序算法(Java 实现):原理 + Demo + 核心分析
java·算法·排序算法
智能工业品检测-奇妙智能2 小时前
AIFlowy如何实现与现有Spring Boot项目的无缝集成?
java·spring boot·后端
從南走到北2 小时前
JAVA无人共享无人健身房物联网结合系统源码支持小程序+公众号+APP+H5
java·物联网·小程序
星期五不见面2 小时前
AI学习(三)openclow启动(2)2026/03/05
学习
Nuopiane2 小时前
MyPal3(3)
java·开发语言
Ama_tor2 小时前
Flask零基础进阶(中)
后端·python·flask
人道领域2 小时前
苍穹外卖:菜品新增功能全流程解析
数据库·后端·状态模式
Chan162 小时前
LeetCode 热题 100 | 矩阵
java·开发语言·数据结构·算法·spring·java-ee·intellij-idea