苍穹外卖小程序端实战:微信登录与商品浏览全解析
“苍穹外卖”这个系列走到第六天终于从管理端切换到了用户端。今天的内容是微信小程序开发核心就两块微信登录、商品浏览。前面几天我们一直在搞后台管理端搭环境、建表、写菜品分类、对接Redis和JWT说实话都是从运营视角看系统。但从今天开始小程序端一接进来整个项目的使用者就从店长变成了顾客技术侧的核心也变成了“怎么通过微信官方能力快速识别用户身份然后再把商品数据安全地吐给小程序”。这篇文章适合正在做这类项目的Java后端同学尤其是那些之前没碰过微信小程序联调、对code换openid和前后端交互比较迷糊的人。我会把今天做的微信登录链路、商品分类浏览的接口设计、小程序端页面对接方式以及联调过程中的坑全部摊开来讲。包括代码、表结构、页面结构基本照着就能复现。1. 先把第六天的目标拆清楚从管理端切到C端小程序1.1 前面五天我们在做什么苍穹外卖这个项目从第一天开始主线就非常清楚。前五天我做的事情基本围绕管理端搭Spring Boot工程、配置MyBatis、设计数据库表、做员工登录、管理菜品分类、菜品增删改查、文件上传下载中间还穿插了Redis缓存店铺营业状态、JWT做登录校验、拦截器做统一鉴权。这些功能有个共同点它们服务的都是“餐厅自己人”。菜品管理、分类管理、营业状态开关都是后台操作页面是电脑端接口路径大多以/admin开头。做这些功能时我的主要精力都放在“数据怎么维护”“权限怎么校验”上整个技术栈是传统的后端管理系统套路。但第六天不一样。这天要把用户端做出来也就是顾客在微信里打开的小程序。小程序端的技术栈、交互方式、安全模型跟网页后台完全不一样很多东西不能照搬。比如用户身份后台管理端是“账密登录”前台用户端就不能让顾客注册账号输密码而是直接依托微信的登录能力。商品浏览也不能简单把后台的列表接口丢出来必须考虑状态过滤、图片域名、分类维度这些细节。所以第六天虽然是“第一天做小程序”但信息密度其实很高。1.2 今天要完成的三个关键点今天的大目标有两个微信登录商品浏览。拆细一点其实有三个关键点必须理清。第一点是微信小程序登录的完整链路。从前端wx.login()拿到一个临时code到后端拿这个code去微信服务端换openid再到后端用openid查用户表、没查到就自动注册然后签JWT返回给前端。这条链路每一步都有讲究后面我会把代码直接贴出来。第二点是商品浏览的接口设计。小程序首页和分类页需要三块数据分类列表、某个分类下的菜品列表、某个分类下的套餐列表。这三个接口路径、入参、返回体长什么样以及为什么不能直接查表返回都需要说清楚。第三点是前后端联调。前端小程序页面怎么写、请求怎么封装、token怎么存、接口跨域和域名白名单怎么处理、图片为什么能显示出来。这些属于实操环节也是初学者最容易卡住的地方。1.3 方案选型为什么不能直接把openid返回给前端先说一个很多人忽略的点。微信登录时传统做法是后端拿code换openid然后给前端返回一个token而不是把openid原样返回。为什么不直接返回openid因为openid是用户的唯一身份标识相当于这个用户在小程序里的身份证号。如果前端存的是openid别人一旦拿到这个id就能伪造请求直接冒充用户身份。我见过不少初学者写接口时直接把openid塞在返回体里交给前端前端每次请求把openid传回后端后端一比对就放行。这个做法能跑通但非常不安全openid一旦泄露等于用户身份泄露。而且微信登录的核心思路是“后端与微信服务端对话”前端只负责提供一次性codecode用完即废真正的身份交换必须发生在服务端。所以我这边最终用JWT token来做自定义登录态前端存token后端解析token里的userId认token不认openid。2. 微信小程序登录从code到token的完整后端链路2.1 微信登录的核心流程微信登录流程最关键的认知是小程序前端永远拿不到用户真正的身份标识。前端只能通过wx.login()拿到一个临时凭证code这个code有效期只有五分钟而且只能用一次。然后前端把这个code发给自己的后端后端再拿着code和appid、secret去请求微信官方接口jscode2session微信服务端才会返回这个用户在小程序下的openid。换句话讲openid会经过两个步骤才能落到我们手里前端拿临时code后端用code换openid。这个设计的目的就是防止前端直接存储敏感身份信息。后端拿到openid之后做两件事先去user表查这个openid是否存在如果存在说明是老用户直接登录如果不存在说明是第一次打开小程序的新用户自动创建一条用户记录然后再登录。这个“查不到就插入”的流程实际上完成了登录与注册的合并。用户确认之后后端生成一个JWTJWT的payload里放userId返回给前端。此后前端每次请求都带着这个token后端通过拦截器解析token就知道当前操作者是谁了。2.2 用户表和实体类的设计登录链路要跑通第一件事是保证数据库里有对应的用户表。我在项目里用的表结构大致是create table user ( id bigint primary key auto_increment comment 主键, openid varchar(45) not null unique comment 微信用户openid, name varchar(32) comment 用户姓名, phone varchar(11) comment 手机号, sex varchar(2) comment 性别, id_number varchar(18) comment 身份证号, avatar varchar(500) comment 头像, create_time datetime comment 注册时间 );注意openid字段我加了unique约束并在代码里用openid作为查询键。这样即使同一个用户删了小程序再重新打开也能通过openid精确匹配到同一条记录不会产生脏数据。对应的实体类是常用的MyBatis风格Data Builder public class User implements Serializable { private static final long serialVersionUID 1L; private Long id; private String openid; private String name; private String phone; private String sex; private String idNumber; private String avatar; private LocalDateTime createTime; }实体类字段跟表字段一一对应。这里有人可能会问name、phone、avatar这些用户信息现在也没地方获取啊为什么一开始就建好因为微信登录之后后续还有授权手机号、获取用户头像昵称这些能力今天先把基础字段铺好后面功能扩展时不用改表。2.3 后端代码实战Controller、Service、Mapper一锅端微信登录后端代码不长但每一层都要写清楚。先看Controller。接口路径我定的是POST /user/user/login入参是前端传上来的code出参是用户ID、openid和token。RestController RequestMapping(/user/user) Slf4j public class UserController { Autowired private UserService userService; Autowired private JwtProperties jwtProperties; PostMapping(/login) public ResultUserLoginVO login(RequestBody UserLoginDTO userLoginDTO) { log.info(微信用户登录code: {}, userLoginDTO.getCode()); User user userService.wxLogin(userLoginDTO.getCode()); MapString, Object claims new HashMap(); claims.put(userId, user.getId()); String token JwtUtil.createJWT( jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims); UserLoginVO userLoginVO UserLoginVO.builder() .id(user.getId()) .openid(user.getOpenid()) .token(token) .build(); return Result.success(userLoginVO); } }这段代码最核心的是JWT的创建。jwtProperties.getUserSecretKey()和getUserTtl()是配置在application.yml里的用户端密钥和有效期它跟管理端的密钥分开管理。这样一个项目里管理端和用户端各自持有一套JWT配置互不干扰也不会出现管理端的token能访问用户端接口这种越权情况。再看Service层Service Slf4j public class UserServiceImpl implements UserService { Autowired private UserMapper userMapper; Override public User wxLogin(String code) { String openid getOpenidByCode(code); if (openid null) { throw new LoginFailedException(微信登录失败无法获取openid); } User user userMapper.getByOpenid(openid); if (user null) { user User.builder() .openid(openid) .createTime(LocalDateTime.now()) .build(); userMapper.insert(user); } return user; } private String getOpenidByCode(String code) { String url https://api.weixin.qq.com/sns/jscode2session?appid appid secret secret js_code code grant_typeauthorization_code; // 发送HTTP请求解析响应中的openid字段 } }这段代码里有两点值得展开。第一getOpenidByCode里拼的是appid和secret它们是后端配置信息绝不能写在前端代码里。secret相当于服务端调用微信接口的密码一旦泄露到小程序代码包任何人都能冒充后端与微信服务端交互。第二为什么先查openid不存在再插入因为微信登录天然具备“首次进入即注册”的属性。用户第一次打开小程序时微信端就会生成一个openid这时候我们后端只需要把这个openid落到自己的user表里就完成了用户的注册。不需要用户再填写手机号、设置用户名密码这跟传统网站登录有很大区别。最后是Mapper层。我用的是注解式SQL比较简洁Mapper public interface UserMapper { Select(select * from user where openid #{openid}) User getByOpenid(String openid); void insert(User user); }insert语句写在XML里因为要拿到自增主键。MyBatis的useGeneratedKeystrue配合keyPropertyid插入后user.getId()就能拿到新用户的主键再把id放进JWT的claims里整个链路就通了。3. 商品浏览分类、菜品、套餐三个接口的设计与实现3.1 商品浏览背后的数据组织商品浏览看起来只是“顾客看到列表”但背后的数据组织不简单。苍穹外卖里商品相关数据主要落在三张表上category分类表、dish菜品表、setmeal套餐表。category表区分了类型type字段为1表示菜品分类为2表示套餐分类。比如“热菜”就是菜品分类“超值套餐”就是套餐分类。dish表属于type1分类下setmeal表属于type2分类下。套餐和菜品之间还有一组关联表因为一个套餐里可能包含多个菜品。这些在后台管里端都已经维护好了。小程序端商品浏览本质上就是把这三类数据按用户视角重新组合输出。用户进入小程序首页看到的第一个维度就是分类点击某个分类之后再看该分类下的商品。所以商品浏览的几个接口基本都是按分类维度的查询。3.2 商品浏览的核心接口设计我设计的是三个接口分别对应分类列表、菜品列表、套餐列表第一个是查询分类列表GET /user/category/list 入参type1为菜品分类2为套餐分类可选 返回分类对象数组这个接口会返回所有可展示的分类。小程序首页的分类导航条就靠它。第二个是查询某个分类下的菜品GET /user/dish/list?categoryId101 返回菜品对象数组且仅返回status1启售的菜品第三个是查询某个分类下的套餐GET /user/setmeal/list?categoryId102 返回套餐对象数组同样只返回启售状态查询菜品接口的Service实现大概是Override public ListDishVO listWithFlavor(Dish dish) { ListDish dishList dishMapper.list(dish); ListDishVO dishVOList new ArrayList(); for (Dish d : dishList) { DishVO dishVO new DishVO(); BeanUtils.copyProperties(d, dishVO); // 查询菜品对应的口味 ListDishFlavor flavors dishFlavorMapper.getByDishId(d.getId()); dishVO.setFlavors(flavors); dishVOList.add(dishVO); } return dishVOList; }注意几个细节。第一dishMapper.list(dish)里的dish对象携带了categoryId和status1SQL里对应的是select * from dish where category_id #{categoryId} and status 1 order by sort desc这样就能在SQL层直接过滤掉停售商品不让“已停售”的菜品出现在顾客面前。这是商品浏览跟后台管理端列表最大的区别管理端能看到所有状态的数据用户端只能看到启售的数据。第二为什么DishVO要额外组装flavors口味列表因为小程序菜品卡片上通常会显示“中辣、微辣、不辣”或者“加冰、去冰”这类规格选项。这个信息存在dish_flavor表里一个菜品对应多个口味普通的Dish实体装不下所以单独封装一个DishVO把口味塞进去。前端拿到flavors之后可以判断菜品能不能选规格、有没有“必选”选项。3.3 图片地址与静态资源映射商品浏览必然会遇到图片。后台管理端上传菜品图片时文件保存在本地的upload目录数据库存的是一段相对路径比如/upload/abc.jpg。小程序端要显示这张图片就必须能通过一个完整的URL访问到它。这里就涉及Spring Boot的静态资源映射。我加了一个配置类Configuration public class WebMvcConfiguration implements WebMvcConfigurer { Value(${sky.upload-path}) private String uploadPath; Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceLocations(file: uploadPath); } }配置之后访问http://localhost:8080/upload/abc.jpg时Spring会直接到uploadPath目录下找abc.jpg这个文件并返回。小程序的image组件src填全路径http://localhost:8080/upload/abc.jpg图片就能正常渲染。这一步很基础但第一次做的时候容易忘。我见过不少人图片显示不出来排查来排查去最后发现就是没加静态资源映射或者映射路径跟数据库里存的路径对不上。上传目录路径的值我放在配置文件里这样部署到服务器时只要改配置不用改代码。4. 小程序前端登录调用、token管理、商品列表渲染4.1 小程序页面结构与基础布局小程序端我采用的是原生小程序框架没引入第三方UI库。页面文件主要分两块首页和分类商品页。首页结构大概是这样顶部搜索框占位今天没做搜索逻辑中间轮播图、分类宫格横向排列的分类入口底部推荐菜品列表分类商品页结构是经典的双列布局左侧纵向分类列表可滚动右侧当前分类下的商品列表可滚动每个商品卡片商品图片、名称、描述、价格页面文件目录大概长这样pages/ index/ index.wxml index.js index.wxss category/ category.wxml category.js category.wxss login/ login.wxml login.js login.wxss其中login页其实只是一个载体。微信登录本质上不一定需要独立的“登录按钮”页面很多小程序进入后静默登录。但为了演示登录交互逻辑我保留了login页作为登录入口。分类页的核心WXML结构是view classcategory-container scroll-view scroll-ytrue classleft-menu view wx:for{{categories}} wx:keyid classmenu-item {{currentIndex index ? active : }} bindtaponSelectCategory >const request (url, method, data) { return new Promise((resolve, reject) { wx.request({ url: baseUrl url, method: method || GET, data: data || {}, header: { content-type: application/json, token: wx.getStorageSync(token) }, success: (res) { if (res.data.code 1) { resolve(res.data); } else if (res.data.code 0) { // 用户登录过期尝试重新登录 wx.showToast({ title: 登录已过期, icon: none }); reLogin(); reject(res.data); } else { reject(res.data); } }, fail: (err) { reject(err); } }); }); };这里有两个设计点很关键。第一个是header里的token字段。后端拦截器规定要从header里取一个叫token的字段如果叫authorization或者别的名字前后端对不上接口就永远报401。我建议在项目最开始就约定好header字段名别写两个地方两套名字。第二个是401自动重新登录。登录过期之后直接跳登录页会很烦更好的做法是捕获到登录态失效的信号后重新调用wx.login()换新code、再换取新token然后重新发起原来的业务请求。小程序端的登录本身是静默无感知的用户根本不需要手动介入。不过今天我只放了重登逻辑的入口具体的“重新排队请求”机制在后续功能完善时可以继续补。4.3 登录调用与商品列表数据加载小程序首页加载时可以先静默登录再拉数据。这里的顺序很关键如果登录都还没成功就去拉商品数据大概率会因为没带token被后端拦截或者虽然能访问但拿不到用户相关数据。我在index.js的onLoad里这样处理onLoad() { this.loginAndLoadData(); }, async loginAndLoadData() { const token wx.getStorageSync(token); if (!token) { await this.silentLogin(); } this.loadCategories(); this.loadDishList(); }, silentLogin() { return new Promise((resolve, reject) { wx.login({ success: async (res) { const resp await request(/user/user/login, POST, { code: res.code }); wx.setStorageSync(token, resp.data.token); wx.setStorageSync(userId, resp.data.id); resolve(); }, fail: (err) reject(err) }); }); }, async loadCategories() { const res await request(/user/category/list, GET, { type: 1 }); this.setData({ categories: res.data }); if (res.data.length 0) { this.loadDishList(res.data[0].id); } }, async loadDishList(categoryId) { const res await request(/user/dish/list, GET, { categoryId }); this.setData({ dishList: res.data }); }这段逻辑很直观先看本地有没有token没有就静默登录拿token然后请求分类拿到分类后默认选中第一个分类并加载这个分类下的菜品列表。注意wx.login()必须在用户授权之前就能调用它不需要用户手动点击也不需要用户同意任何授权弹窗。它只是返回一个临时code真正拿到用户信息的主权在服务端。5. 联调现场高频问题实录与登录态设计复盘5.1 联调高频问题速查表第六天联调过程中遇到的问题我可以提前给你打个预防针。下面这些场景基本覆盖了大多数初学者会卡住的点。现象可能原因解决办法登录接口报错微信返回40029code无效或已过期确认wx.login的code没有被重复使用每次登录都重新调用wx.login获取新code登录接口报错微信返回40013appid不合法检查后端配置的appid是否是小程序自己的别填成公众号或其他应用的请求接口返回401token没传或失效检查请求头字段名是否为后端拦截器要求的token检查JWT密钥是否一致商品接口能访问但拿不到数据分类id错误或该分类下没有启售商品先确认数据库里该categoryId下有没有status1的记录图片显示404静态资源映射没配置或路径不对检查addResourceHandlers确认上传目录绝对路径正确小程序开发者工具提示域名不合法本地调试时请求了http://localhost开发阶段在开发者工具里勾选“不校验合法域名”新增用户后无法获取userIdinsert语句没配置自增主键回填在insert的XML中配置useGeneratedKeystrue和keyPropertyid接口返回的price是整数没有小数点数据库字段类型或JSON序列化问题检查price字段类型是否为decimal统一在VO中保留两位小数里面最有迷惑性的是第一个。code的过期问题发生在你“手动重复执行”的时候。我调试时习惯用postman保存上一次的请求体第二次再跑发现报错40029就会以为是接口问题。其实微信的code是一次性的postman重放上一次的code当然失效。解决方法是每次都在小程序里重新触发wx.login再从network面板里复制最新请求。5.2 登录态和token的几个设计心得做完微信登录之后有几个点我想单独拎出来说它们不是代码层面必须写死的东西但设计得好不好直接影响后续功能的开发成本。第一个是用户端和管理端的JWT最好分开配置。我在application.yml里配了两套sky.jwt配置一套是adminSecretKey和管理端过期时间另一套是userSecretKey和用户端过期时间。这样管理端接口和用户端接口可以使用不同的校验拦截器不会出现串token的问题。如果共用一套密钥理论上存在管理端token误用被用户端接口接收的可能虽然业务上不太会发生但分开了更安心。第二个是token有效期不要设置成永久。永久token看着方便但一旦泄露用户身份就一直处于风险中。我给用户端token设置的过期时间是24小时对普通外卖小程序来说一天登录一次属于正常体验。如果用户第二天打开小程序发现登录态还在可以直接通过静默登录再拿一个新token过程无感。第三个是session_key这个返回值。微信的jscode2session接口除了返回openid还会返回session_key。session_key不是用来登录的它主要用于后续解密手机号、解密用户敏感信息。很多初学者第一次看到这个字段会以为要把它存进数据库实际上它不需要入库可以在需要解密时再次通过code换取或者临时缓存起来配合解密。今天没有用到解密手机号的场景所以我没有持久化它。5.3 后续扩展购物车与订单的入场准备商品浏览做完小程序端的骨架基本搭起来了。下一步加入购物车、下单、支付功能时有两样东西今天已经顺带铺好了。一个是用户表。今天新增用户时已经生成了userId并存进了JWT payload。后续创建购物车记录、创建订单时我们都可以通过解析token拿到那个userId从而把订单数据落到具体用户头上。另一个是商品浏览接口的状态过滤规范。用户端能看到的商品都是启售状态那么后续写“加购物车”“提交订单”接口时也必须保持同样的校验逻辑不仅入参要合法商品本身要处于启售状态才能继续走下单流程。今天把用户端“只能看到启售商品”的规则立下来后面所有C端接口都要跟这个规则保持一致。再说一个小技巧。商品浏览接口返回的数据结构里菜品对象包含一个description描述字段小程序页面这一步可以先不展示但最好提前准备好样式位置。外卖场景下顾客很看重“这个菜是什么口味、有没有辣”未来运营人员一旦补充了描述文案前端不需要重新发版就能显示出来这种小设计能让后续迭代省很多事。第六天做到这里小程序端从无到有已经有了第一个完整业务闭环用户静默登录、身份识别、分类浏览、菜品列表展示。整个过程回头看核心其实不是一个复杂算法或高性能架构而是把微信登录规范和用户端商品查询规则理清楚。只要这两个链路稳了购物车、订单、支付这些后续功能基本都是在这个骨架上继续堆肉。

相关新闻

AnyPS5跨平台串流实战:自建低延迟主机远程控制方案

AnyPS5跨平台串流实战:自建低延迟主机远程控制方案

1. 从“AnyPS5”这个标题说起:一个跨平台串流工具的设计野心第一次看到“AnyPS5”这个标题,我脑子里蹦出来的第一个念头是:这名字起得挺狂。Any这个词在技术圈里通常意味着“跨平台”“通用”“不挑环境”,而PS5代表的是一个相对封…

2026/10/14 7:15:36 阅读更多 →
SpringBoot+Vue构建高校竞赛报名系统实践

SpringBoot+Vue构建高校竞赛报名系统实践

1. 项目背景与核心价值大学生科技竞赛活动报名系统是高校创新创业教育中不可或缺的支撑平台。传统线下报名方式存在信息不对称、流程繁琐、数据统计困难等问题。我们团队基于SpringBootVue技术栈开发的这套系统,实现了从项目发布、团队报名、材料提交到评审管理的全…

2026/10/14 7:15:36 阅读更多 →
MATLAB手写多层感知机:反向传播实战与调参避坑指南

MATLAB手写多层感知机:反向传播实战与调参避坑指南

简介:这是一份用Matlab从零搭建多层感知机的完整代码包,面向机器学习初学者与需要手写BP反向传播实验的本科生、研究生。资源由三个全连接层构成,共11个文件,包含9个.m脚本和2个.mat数据/权重文件,压缩包仅13KB。脚本涵…

2026/10/14 7:15:36 阅读更多 →

最新新闻

AI辅助量化策略开发:从零搭建ETF轮动回测框架

AI辅助量化策略开发:从零搭建ETF轮动回测框架

1. 为什么说现在是个人做量化的最好时机我接触量化交易差不多有七八年了,最早那会儿,个人想做一套自己的策略,门槛高得离谱。你得自己搭数据库、自己写回测框架、自己处理除权除息、自己搞行情接口,光是数据清洗就能耗掉大半个月。…

2026/10/14 8:10:50 阅读更多 →
M/o/Vfuscator 入门示例:用单条 mov 指令编译 prime.c,与 GCC 输出逐行对比

M/o/Vfuscator 入门示例:用单条 mov 指令编译 prime.c,与 GCC 输出逐行对比

编译器 【免费下载链接】movfuscator The single instruction C compiler 项目地址: https://gitcode.com/gh_mirrors/mo/movfuscator 点击查看 免费下载 本文以 movfuscator 仓库中的 overview/ 目录为例,展示如何用 M/o/Vfuscator 编译器(…

2026/10/14 8:10:50 阅读更多 →
openrig 装配指南:Node.js、tmux 与 Claude Code/Codex 本地工作台搭建

openrig 装配指南:Node.js、tmux 与 Claude Code/Codex 本地工作台搭建

1. 从 openrig 这个名字说起:它到底想解决什么问题第一次看到openrig这个词,我脑子里蹦出来的不是某个具体工具,而是一种"把散装零件拼成一台整机"的直觉。rig 在英文里本意是"装配、搭建",在工程语境里常指把…

2026/10/14 8:10:50 阅读更多 →
ECCV2020三维视觉技术路线图:点云处理与3D检测的范式跃迁

ECCV2020三维视觉技术路线图:点云处理与3D检测的范式跃迁

1. 这不是论文清单,而是一份三维视觉领域的技术路线图ECCV 2020那届会议我全程跟下来了,当时在苏黎世现场听oral报告时,就明显感觉到——三维视觉的范式正在悄悄转移。过去几年大家还在争论“点云该不该用MLP堆叠”,到了2020年&am…

2026/10/14 8:10:50 阅读更多 →
REA 接入前的技术核对:静态分析、后端和 MCP 分别检查什么

REA 接入前的技术核对:静态分析、后端和 MCP 分别检查什么

REA 接入前的技术核对:静态分析、后端和 MCP 分别检查什么 准备把 REA 接到 Agent 时,先区分三个问题:分析输入是什么,对应工作流需要什么依赖,Agent 是否真的连到了这项能力。它们出错时的表现可能相似,处…

2026/10/14 8:10:50 阅读更多 →
照片隐私保护:EXIF元数据清除工具与技术解析

照片隐私保护:EXIF元数据清除工具与技术解析

1. 为什么我们需要关注照片隐私问题上周帮朋友处理一张手机拍摄的证件照时,无意间用专业软件查看了它的EXIF信息,结果发现里面完整记录了拍摄时间、GPS坐标、手机型号甚至系统版本。这让我意识到——我们每天随手分享的照片,可能正在泄露大量…

2026/10/14 8:09:50 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →