新闻详情

新闻详情

首页 / 资讯中心 / 详情

Flask+微信小程序搭建同城二手交易系统实战

发布时间:2026/10/2 1:23:26来源:尧图网络
Flask+微信小程序搭建同城二手交易系统实战
说实话接到这个同城二手交易系统的需求时我的第一反应是这不就是个“看起来不难、做起来琐碎”的典型项目吗。等真正动手用 Python Flask 写后端接口、微信小程序做用户端前后花了一个多月才发现真正耗时间的不是某个单一功能而是把登录、发布、列表、下单、站内沟通这一整条链路串起来的全过程。这篇文章不是在讲“hello world”它面向的是准备独立把一个前后端分离的完整项目跑起来的人。我会从技术选型讲起带过数据库设计再落到前后端的关键代码最后把上线时踩过的坑一并交代清楚。1. 项目概述与整体设计思路1.1 这个项目到底做了什么同城二手交易系统的核心逻辑并不复杂一句话概括用户可以在小程序里发布闲置物品浏览同城其他人发布的东西对感兴趣的物品发起沟通或直接下单完成线下交易。和闲鱼这类大平台相比这个项目砍掉了复杂的信用体系、担保支付、物流追踪把重心放在“发布—发现—联系—成交”这条最短路径上。功能清单大致是这几块微信授权登录、商品发布多图上传、分类选择、价格填写、商品列表分类筛选、关键词搜索、分页加载、商品详情查看大图、联系卖家、收藏、站内留言沟通、订单创建与管理、个人中心我发布的、我收藏的、我买到的、我卖出的。这里面有两点和普通后台管理系统很不一样。第一商品发布不是一个简单的表单提交它涉及图片上传的时序问题得先传完图拿到 URL再关联到商品数据上前端要做“提交中”的 loading 状态后端也要设计独立的图片上传接口。第二“同城”这个属性决定了列表页需要地理位置信息虽然为了简化可以先用用户手动填写的城市字段来过滤但如果后面想做得更真实就得接入微信的wx.getLocation用经纬度做距离排序和范围筛选。1.2 为什么是 Flask 微信小程序这个组合先说 Flask。Python 后端框架里 Django 和 Flask 是最常用的两个Django 自带 Admin 后台、ORM、认证体系适合大型项目但二手交易系统这种体量用 Django 反而会觉得“重”模型定义、中间件、模板引擎这些默认配置有一大半用不上。Flask 轻量、自由你想怎么组织代码就怎么组织非常适合一个人掌控全部代码的场景。而且 Flask 的生态足够成熟SQLAlchemy 做 ORM、JWT 做登录态、flask-cors 解决跨域都有现成的库遇到问题查资料也方便。前端为什么选微信小程序而不是 H5核心原因是二手交易天然依赖微信的社交关系链。用户看中一件商品想问问卖家“东西还在吗”最顺滑的方式就是跳转到微信聊天小程序里可以直接wx.openChat拉起会话H5 做不到这种原生体验。再加上微信小程序的分享卡片、订阅消息都很适合商品传播和交易提醒。当然小程序也有它的限制比如必须 HTTPS、必须配置合法域名、部分 API 需要用户授权这些限制后面会专门讲。2. 技术栈选型与核心模块拆分2.1 Flask 后端选型的关键点Flask 写接口有一个推荐的项目组织方式app 工厂模式加蓝图Blueprint。不要把所有路由堆在一个app.py里那样几百行之后连自己都找不到某个接口在哪。我习惯的目录结构大致是这样flask_app/ ├── app/ │ ├── __init__.py # 创建 app、注册蓝图、初始化扩展 │ ├── models/ # SQLAlchemy 模型 │ │ ├── user.py │ │ ├── product.py │ │ └── order.py │ ├── api/ # 蓝图路由 │ │ ├── auth.py │ │ ├── product.py │ │ ├── order.py │ │ └── message.py │ ├── utils/ # 通用工具 │ │ ├── response.py # 统一返回格式 │ │ └── jwt_auth.py # 登录装饰器 │ └── config.py # 配置 ├── uploads/ # 图片上传目录 ├── requirements.txt └── run.py依赖方面我用的核心库有flask、flask-sqlalchemy、flask-cors、pyjwt、requests用于向微信服务器换取 openid、Pillow图片压缩。requests这个库在登录环节是刚需因为后端拿用户的code换 openid 时必须调用微信的接口躲不开。还有一个容易被忽略的点flask-cors必须注册。开发的时候前端跑在微信开发者工具里请求的域名是http://localhost:5000后端如果不允许跨域小程序端会直接报错。后面部署到正式环境虽然前端和后端都在 HTTPS 域名下了但小程序端域名和小程序自身域名并不一致跨域问题依然存在所以 CORS 配置不是临时措施是一开始就要做好的。2.2 小程序端原生还是框架小程序端我当时纠结过用原生还是 Taro/uni-app。最后选了原生理由有三个第一这个项目没有多端需求不需要一套代码同时跑微信、支付宝、抖音第二原生小程序包体积小编译快调试起来最直接第三原生语法本身不复杂页面就是 WXML JS WXSS对后端出身的人来说反而更容易理解数据流向。原生小程序的目录结构我会按业务模块分miniprogram/ ├── app.js ├── app.json ├── pages/ │ ├── index/ # 首页商品列表 │ ├── detail/ # 商品详情 │ ├── publish/ # 发布商品 │ ├── order/ # 订单列表 │ ├── message/ # 站内信 │ └── mine/ # 个人中心 ├── components/ # 自定义组件 ├── utils/ │ └── request.js # 请求封装 └── static/页面之间的跳转用原生路由传参通过 URL query 或者全局getApp().globalData。这里有一个经验像“从列表页点进详情页”这种场景可以用 URL 传productId但像“发布成功返回首页并刷新列表”这种跨页面通信用 URL 参数就不够活了我会用 eventBus 或者直接在onShow里重新请求数据。后者在小程序里更简单可靠。2.3 核心业务模块与接口清单在写代码之前先把接口设计清楚前后端并行开发的时候才不会互相等。我整理了一份接口清单先和后端对好再开始两边各自开发。这个项目最终定下来的主要接口大概这些模块接口方法说明认证/api/auth/loginPOST微信 code 换登录态认证/api/auth/checkGET校验登录态是否有效商品/api/productsGET分页列表支持分类、关键词、排序商品/api/products/GET商品详情商品/api/productsPOST发布商品商品/api/products/PUT下架/编辑商品收藏/api/favoritesGET/POST收藏列表/添加收藏订单/api/ordersPOST创建订单订单/api/ordersGET按角色查询订单列表消息/api/messagesPOST/GET发送/查询站内信接口设计上有一个原则列表接口不要返回全量数据必须分页。这既是为了后端性能也是小程序端“加载更多”功能的数据基础。我统一用page和page_size两个参数返回结构是{ list: [...], total: 100, has_more: true }前端拿到has_more就知道还有没有下一页。3. 数据库设计与后端 API 实现3.1 数据表结构设计数据库用的是 MySQL 5.7ORM 用 SQLAlchemy。表结构我设计得比较克制一共六张核心表减少不必要的关联查询user用户表字段包括 openid、昵称、头像、城市、注册时间category分类表字段包括名称、图标、排序值product商品表字段包括标题、描述、价格、图片JSON 数组、分类、发布者、状态、浏览量、位置favorite收藏表user_id product_id 联合唯一order订单表订单号、商品、买家、卖家、金额、状态、创建时间message站内信表发送者、接收者、商品、内容、是否已读商品表是核心状态字段status我用0-在售 1-已下架 2-已卖出三个值。把“已卖出”单独分出来很重要因为订单创建后商品就该不可见了但历史订单里的商品信息仍然需要保留。帖一下 user 和 product 两个模型的核心代码只是示例完整字段可以按需扩展class User(db.Model): __tablename__ user id db.Column(db.Integer, primary_keyTrue) openid db.Column(db.String(64), uniqueTrue, nullableFalse) nickname db.Column(db.String(64)) avatar db.Column(db.String(256)) city db.Column(db.String(32)) created_at db.Column(db.DateTime, defaultdatetime.utcnow) class Product(db.Model): __tablename__ product id db.Column(db.Integer, primary_keyTrue) user_id db.Column(db.Integer, db.ForeignKey(user.id)) category_id db.Column(db.Integer, db.ForeignKey(category.id)) title db.Column(db.String(128), nullableFalse) desc db.Column(db.Text) price db.Column(db.Numeric(10, 2)) original_price db.Column(db.Numeric(10, 2)) images db.Column(db.Text) # JSON 字符串如 [/uploads/1.jpg] city db.Column(db.String(32)) status db.Column(db.SmallInteger, default0) view_count db.Column(db.Integer, default0) created_at db.Column(db.DateTime, defaultdatetime.utcnow)有几个设计上的细节值得说一下。一是images用db.Text存 JSON 字符串而不是单独建一张图片表。对于没有复杂图片处理需求的二手交易系统这样做查询少一次 JOIN实现简单前端解析JSON.parse就行。二是price用Numeric(10,2)不要用 FloatFloat 在涉及金额计算时会有精度问题Numeric能保证精确到分。三是所有表都有created_at方便后续做“最新发布排序”。3.2 用户登录微信授权 JWT微信小程序的登录流程是前端wx.login拿到临时 code传给后端后端拿着 code 加上小程序的 AppID 和 AppSecret调用微信接口换取 openid然后后端用 openid 作为唯一标识查数据库没有则创建新用户最后签发自己的登录态 token。这个 token 我选的是 JWT。JWT 的好处是无状态后端不用存 session小程序每次请求在 header 里带Authorization: Bearer token后端通过解析 token 拿到用户 ID。实现起来也不复杂# 登录接口核心逻辑 def login(): code request.json.get(code) resp requests.get( https://api.weixin.qq.com/sns/jscode2session, params{ appid: app.config[APP_ID], secret: app.config[APP_SECRET], js_code: code, grant_type: authorization_code } ).json() openid resp.get(openid) if not openid: return error(登录失败code 无效) user User.query.filter_by(openidopenid).first() if not user: user User(openidopenid) db.session.add(user) db.session.commit() token jwt.encode( {uid: user.id, exp: datetime.utcnow() timedelta(days7)}, app.config[SECRET_KEY], algorithmHS256 ) return success({token: token, user: user.to_dict()})封装一个登录装饰器后续需要登录的接口直接加上from functools import wraps def login_required(f): wraps(f) def wrapper(*args, **kwargs): auth request.headers.get(Authorization, ) token auth.replace(Bearer , ) try: payload jwt.decode(token, app.config[SECRET_KEY], algorithms[HS256]) user User.query.get(payload[uid]) if not user: raise jwt.InvalidTokenError g.user user except Exception: return error(请先登录, 401) return f(*args, **kwargs) return wrapper这里有个实际体验微信的 code 是一次性的前端必须每次wx.login都拿最新的 code 来换。有些同学会把 code 缓存下来多次使用微信会直接报错。另外AppSecret 一定不能放在小程序前端代码里要留在后端否则任何人都能拿着你的 AppSecret 调用微信接口风险非常大。3.3 商品发布与列表接口发布接口是文件上传和商品信息分开的。前端先调上传图片接口拿到图片 URL 列表后再随商品信息一起提交。这样做的原因是小程序端wx.uploadFile上传的是二进制文件而商品信息是 JSON混在一次请求里反而容易出问题还会影响重试逻辑。商品列表接口是查询频率最高的接口索引一定要建好。category_id、status、created_at这三个字段组合一个复合索引就可以。查询逻辑也简单def get_products(): page request.args.get(page, 1, typeint) page_size request.args.get(page_size, 10, typeint) query Product.query.filter_by(status0) if request.args.get(category_id): query query.filter_by(category_idint(request.args[category_id])) if request.args.get(keyword): query query.filter(Product.title.like(f%{request.args[keyword]}%)) if request.args.get(city): query query.filter_by(cityrequest.args[city]) total query.count() items query.order_by(Product.created_at.desc()) \ .offset((page - 1) * page_size) \ .limit(page_size).all() return success({ list: [p.to_dict() for p in items], total: total, has_more: page * page_size total })关键词搜索这里我先用了简单的like数据量小的时候没问题。但如果商品量到了上万条like %xx%不走索引会全表扫描到时候就得换全文索引或者接入 Elasticsearch。做项目的时候要心里有数当前方案能撑到什么量级什么时候该升级。查看详情时浏览量view_count要加 1。这里有个细节用户自己看自己的商品不应该累加浏览量所以接口里判断了一下product.user_id ! g.user.id。这个小判断不影响功能但体现了“数据准确性”的意识。3.4 订单与站内信功能订单创建是并发问题比较集中的地方后面会细说。这里先讲设计订单表里除了商品 ID还冗余存了product_title、price、seller_id、buyer_id订单创建时把商品当前的价格快照存进来。为什么冗余因为商品之后可能改价、下架甚至被删掉但历史订单必须保留下单那一刻的商品信息。站内信的设计是“商品维度 用户维度”。就是每条消息都挂在某个商品下关联发送者和接收者。这样实现起来简单详情页里用户可以直接看到“关于这个商品的所有历史留言”很像论坛的楼中楼。列表页需要显示“谁给我发过消息、最后一条内容、是否已读”用一个聚合查询按商品分组取最新消息即可。我额外做了一个收件箱逻辑如果有人在你发布的商品下留言你会收到一条未读消息。这个未读数量返回给前端在小程序 tabBar 上做红点提示。功能虽小但对交易系统的体验提升非常明显买家知道卖家能看到自己的留言沟通意愿会强很多。4. 小程序前端的关键实现细节4.1 请求封装与统一登录处理小程序端所有请求都走一个封装的request.js不要在每一个页面里直接写wx.request不然后面要改 baseURL 或者统一处理 401你会想哭。我的封装思路是wx.request包一层 PromisebaseURL 用一个常量统一管理请求时自动带Authorizationheader收到响应后统一解包遇到 401 就清理本地登录态并跳转登录页。const BASE_URL https://your-api-domain.com function request(path, method, data, options {}) { return new Promise((resolve, reject) { wx.request({ url: ${BASE_URL}${path}, method: method || GET, data: data || {}, header: { Content-Type: application/json, Authorization: Bearer (wx.getStorageSync(token) || ) }, success: (res) { if (res.statusCode 401) { wx.removeStorageSync(token) wx.redirectTo({ url: /pages/login/login }) reject(res) return } resolve(res.data) }, fail: (err) { wx.showToast({ title: 网络异常, icon: none }) reject(err) } }) }) } module.exports { request, BASE_URL }这里有一个很关键的点小程序里wx.showToast的icon: none才能显示纯文字提示默认 icon 只有成功和加载两种。很多新手第一次写网络请求失败提示发现 toast 不出来就是因为没加icon: none。4.2 列表页的加载更多正确写法“加载更多”是列表类小程序的标配功能看起来简单真正写的时候容易出一堆问题重复请求、数据叠加错乱、没有 loading 提示、触底判断不准确。微信小程序里实现加载更多靠的是页面的onReachBottom生命周期触底时自动触发。我的标准模板是先加一个状态锁防止滚动到底部时连续触发多个请求let page 1 let pageSize 10 let loading false let hasMore true onReachBottom() { if (!hasMore || loading) return this.loadProducts() } loadProducts() { loading true request(/api/products, GET, { page: page 1, page_size: pageSize }) .then(res { const list [...this.data.products, ...res.data.list] this.setData({ products: list }) page 1 hasMore res.data.has_more }) .finally(() { loading false }) }这里我觉得最容易翻车的点是忘记finally。正常情况下请求失败后也要把loading置回 false否则用户触底一次失败后这个列表就永远加载不出更多了。页面底部再放一个固定文案提示hasMore为 false 时显示“没有更多了”为 true 且 loading 时显示“加载中”这样用户能感知到状态。4.3 图片上传与发布表单图片上传用wx.uploadFile一次只能传一个文件所以多图场景要循环调用。发布商品时用户选择完图片后我先在本地预览等用户真正点击“发布”时才统一上传。这个时机取舍很重要如果选完图就立刻上传用户最后取消发布服务器上会留一堆没人用的废图。上传的代码核心function uploadImage(filePath) { return new Promise((resolve, reject) { wx.uploadFile({ url: ${BASE_URL}/api/upload, filePath: filePath, name: file, header: { Authorization: Bearer (wx.getStorageSync(token) || ) }, success: (res) { const data JSON.parse(res.data) resolve(data.url) }, fail: reject }) }) }注意name: file必须和后端接口里request.files[file]的字段名对应上很多联调问题都出在这个字段名不一致上。后端收到图片后我会用Pillow压缩一遍限制最长边 1280px质量 80图片文件体积能缩小一半以上既能加快上传也能减小服务器磁盘占用。发布表单里的一个体验坑用户填了价格后点提交如果图片还没传完页面会直接卡住没有反馈。所以发布按钮的点击事件里第一步就是wx.showLoading({ title: 发布中 })最后在wx.hideLoading里收尾。上传三张图的等待时间大概几秒没有 loading 提示的话用户很容易以为没点到再点几次就重复发布了。4.4 个人中心与订单状态流转个人中心的数据来源是多个接口的组合用户信息、我发布的商品数、收藏数量、未读消息数。首次进入页面时并行请求而不是串行请求减少白屏时间。小程序端Promise.all就能实现Promise.all([ request(/api/user/info), request(/api/products/mine), request(/api/favorites/count), request(/api/messages/unread) ]).then(([userInfo, products, favCount, msgCount]) { this.setData({ userInfo, products, favCount, msgCount }) })订单状态流转是业务里最容易搞混的部分。我设计的状态机是0-待见面交易 1-已完成 2-已取消。买家创建订单后进入“待见面交易”卖家看到订单后联系买家线下成交双方确认后买家把订单标记为“已完成”如果中途一方放弃就标记“已取消”。考虑到个人主体的小程序无法开通微信支付我在这个项目里没有做线上支付闭环而是把交易引导到线下见面付款。这是二手交易场景的真实选择也省掉了支付牌照、商户号、支付证书这一大堆麻烦。如果你后续要接支付建议直接看微信支付官方文档按小程序商户号接入流程走。5. 从本机到线上部署与上线实战5.1 本机环境搭建与项目启动先说开发环境的准备。本机装 Python 3.8MySQL 5.7微信开发者工具。Python 环境建议用虚拟环境不要直接装全局避免不同项目依赖冲突。pip install -r requirements.txt之前先python -m venv venvWindows 下激活是venv\Scripts\activateMac/Linux 下是source venv/bin/activate。启动后端flask run或者python run.py监听在127.0.0.1:5000。VSCode 里配置 Python 调试环境时把launch.json里的python路径指向虚拟环境否则断点可能打不进去。小程序端在微信开发者工具里导入项目填上自己的 AppID然后在“详情-本地设置”勾选“不校验合法域名”。这一步是开发期调试的关键不勾的话真机预览请求http://localhost:5000会被拦下来。但记住这只是开发期的便利开关上线前必须关掉并走正式合法域名。5.2 服务器部署的核心步骤正式部署我的选择是一台云服务器LinuxNginx 做反向代理Gunicorn 跑 FlaskMySQL 照旧图片静态文件放在服务器目录里由 Nginx 直接托管。部署第一步是代码同步直接把项目 clone 到服务器安装依赖跑数据库迁移脚本。第二步是启动 Gunicorngunicorn -w 4 -b 127.0.0.1:8000 run:app-w 4表示 4 个 worker 进程。这个数字不是越大越好一般按服务器的 CPU 核数来2 核机器开 4 个 worker 比较合适不然进程切换开销反而拖慢速度。然后配置 Nginx核心部分是反向代理和静态文件路径server { listen 80; server_name your-api-domain.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /uploads/ { alias /var/www/flask_app/uploads/; } }配置完成后nginx -s reload生效。这里有一个很多新手容易踩的坑Gunicorn 只监听 127.0.0.1不要直接暴露到公网公网请求必须走 Nginx这样既能统一做静态文件处理也能在 Nginx 层做请求大小限制、日志格式控制。5.3 上线前必须处理的三个问题第一个是 HTTPS。微信小程序要求所有请求域名必须是 HTTPS而且证书是受信任的。我用的方案是云服务商提供的免费证书一年一换。证书配置完成要记得验证一下有些证书链不完整浏览器能打开但小程序请求直接失败。第二个是合法域名配置。在微信公众平台后台把后端域名配置到“服务器域名-request 合法域名”和“uploadFile 合法域名”里。注意 uploadFile 和 request 是分开配置的WebSocket、downloadFile 也是独立条目别漏了上传图片那个域名。配置后一般等几分钟生效真机预览才能正常请求。第三个是媒体资源策略。图片如果直接存服务器本地磁盘占用会越来越大备份也会变麻烦。项目上线后如果反馈不错可以尽早切到云对象存储服务图片直传 OSS后端只存 URL服务器压力会小很多。切换时图片 URL 字段格式不变前端基本不用动。6. 常见问题排查与避坑实录6.1 跨域与请求 403 问题小程序请求后端接口报 403多半是 CORS 问题。我开发时使用flask-cors统一解决from flask_cors import CORS CORS(app, resources{r/api/*: {origins: *}})正式环境里你可以把 origins 收紧为具体的小程序域名但开发期用*就行。还有一种 403 是 Nginx 配置不对请求到了 Nginx 但没有转发成功这时候看 Nginx 的 error log路径写没写对、代理地址是不是127.0.0.1:8000一眼就能看出来。这里我想多说一句排查问题的顺序遇到接口报错先看小程序调试器里的 Network 面板看 HTTP 状态码和响应体再看后端日志最后看 Nginx 日志。很多同学一上来就怀疑代码逻辑绕了一大圈发现是域名配置问题浪费时间。6.2 小程序图片上传失败图片上传失败常见有三类原因。第一类是wx.uploadFile返回的不是 JSON 字符串而是字符串本身。因为微信把响应体当文本返回后端返回 JSON 时前端必须JSON.parse(res.data)再取数据否则会拿到 undefined。第二类是文件大小限制。Nginx 默认client_max_body_size是 1m超过 1M 的图片直接返回 413。上传图片是高频操作必须显式配大一点client_max_body_size 10m;第三类是并发上传把服务器压垮。小程序多图上传是逐张循环调用的如果一次传 9 张图后端同时收到 9 个请求开发环境没问题但低配服务器可能扛不住。我在前端做了并发控制最多同时传 3 张其余排队const concurrency 3 let index 0 async function uploadQueue() { const tasks [] for (let i 0; i concurrency; i) { tasks.push(runWorker()) } await Promise.all(tasks) }6.3 并发下单的数据一致性订单创建时有一个经典问题两个用户同时看中同一件商品几乎同时下单怎么办如果不控制会出现两个订单都创建成功但商品只有一件的情况。方案其实很简单用数据库的原子更新做“乐观锁”result Product.query.filter_by( idproduct_id, status0 ).update({ status: 2 }) db.session.commit() if result 0: return error(商品已被购买或以被下架)update返回影响的行数。如果返回 0说明商品已经不是“在售”状态第二个请求直接拒绝。这一步在代码里只多写了两三行但避免了最严重的交易事故。数据库的原子操作在这里比 Python 层的 if 判断可靠得多因为多个进程同时执行时if 判断会有竞态条件而数据库的行锁会保证只有一个 update 成功。6.4 数据导出和运营辅助的实用小功能运营一个二手交易平台免不了要看每天有多少人发布、多少人下单、哪些商品浏览量高。我写了个简单的管理脚本不是线上页面而是本机运行的数据导出工具利用 Python 直接连 MySQL用openpyxl把订单、商品数据导出成 Excel 表格import openpyxl from openpyxl.styles import Font wb openpyxl.Workbook() ws wb.active ws.title 今日订单 ws.append([订单号, 商品, 价格, 买家, 卖家, 时间]) for row in today_orders: ws.append([row.order_no, row.product_title, float(row.price), row.buyer_name, row.seller_name, row.created_at]) wb.save(运营报表.xlsx)导出成 Excel 的好处是运营同学不用登录系统就能看数据也很方便临时统计。这个脚本我加了定时任务每天凌晨自动生成前一天的报表上传到对象存储运营直接拿链接下载。虽然是小项目但这种自动化的小工具省下来的时间非常可观。7. 最后分享一点实战心得这个项目从零到上线我最大的体会是做一个完整项目最难的从来不是某一个技术点而是所有环节拼接在一起时不掉链子。微信登录、列表分页、图片上传、订单并发单独拿出来都有现成的教程但把它们组合成一个能上线、能真实使用的系统就需要你把数据流、异常流、权限控制都过一遍。如果你也想复刻这个项目我的建议是先做减法。不要一上来就想着做社区、做评论、做积分体系先把“发布—发现—联系—成交”这条主链路跑通后续的需求都是在主链路稳定后自然长出来的。功能少了可以慢慢加但数据模型设计和接口约定在一开始就想清楚后面会省掉大量返工。还有一点是多给自己留调试的时间。小程序端和 Flask 后端联调时经常出现两边理解不一致的情况比如字段名大小写、时间格式、金额单位。我的习惯是后端先把所有接口用 Postman 自测一遍再让前端联调这样排查问题时能确定到底是谁的问题。一个人同时写前后端更要做好接口文档哪怕只是简单的 Excel 表格也能让你两个星期后回来看代码时少死很多脑细胞。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

GitHub镜像站高效同步与搭建实战:从原理到排查 2026/10/2 2:14:12

GitHub镜像站高效同步与搭建实战:从原理到排查

GitHub用得多了,你就会发现一件事:仓库越来越多、团队越来越分散,偶尔还会遇到网络抖动导致代码拉不下来、页面打不开、下载到一半断掉的情况。这类问题在网上被讨论得很多,而大家最终会不约而同地聊到一个词——GitHub镜像站。我…

阅读更多 →
一个小小的开始 2026/10/2 2:14:12

一个小小的开始

回归正题,这是我的第一篇博客,仅仅做自己记录之用,也不会有人注意到这里的。离暑假完结还有些日头,我目标先学完c语言与51单片机。视情况学习stem32与数据结构。我一直很迷茫自己应该往软件还是硬件方向去学习,最后还是…

阅读更多 →
黄白助手 第 038 个开关:禁用设置页第三方信息共享清单的位置、验证方法与风险边界 2026/10/2 2:14:11

黄白助手 第 038 个开关:禁用设置页第三方信息共享清单的位置、验证方法与风险边界

🔥 个人主页: 杨利杰YJlio ❄️ 个人专栏: 《Windows 疑难杂症与工单复盘案例库》 《Sysinternals实战教程》 《WINDOWS教程》 《Windows PowerShell 实战》 《IOS插件分析测试》 《超简单:用Python让Excel飞起来》…

阅读更多 →
黄白助手 第 036 个开关:禁用设置页个人信息收集清单的位置、验证方法与风险边界 2026/10/2 2:14:11

黄白助手 第 036 个开关:禁用设置页个人信息收集清单的位置、验证方法与风险边界

🔥 个人主页: 杨利杰YJlio ❄️ 个人专栏: 《Windows 疑难杂症与工单复盘案例库》 《Sysinternals实战教程》 《WINDOWS教程》 《Windows PowerShell 实战》 《IOS插件分析测试》 《超简单:用Python让Excel飞起来》…

阅读更多 →
黄白助手 第 039 个开关:禁用自拍表情按钮的位置、验证方法与风险边界 2026/10/2 2:14:10

黄白助手 第 039 个开关:禁用自拍表情按钮的位置、验证方法与风险边界

🔥 个人主页: 杨利杰YJlio ❄️ 个人专栏: 《Windows 疑难杂症与工单复盘案例库》 《Sysinternals实战教程》 《WINDOWS教程》 《Windows PowerShell 实战》 《IOS插件分析测试》 《超简单:用Python让Excel飞起来》…

阅读更多 →
基于SpringBoot的智能化停车场管理系统二次开发实战解析 2026/10/2 2:14:04

基于SpringBoot的智能化停车场管理系统二次开发实战解析

毕业设计拿到“智能化停车场管理系统”这种题目,又不想从零开始写代码,最终选择基于SpringBoot的源码来二次开发,这应该是很多计算机专业同学的真实路径。我前阵子刚好帮一个学弟梳理过一套类似的项目,今天把整个过程沉淀下来&…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉