☰
Flask+微信小程序+Android:服装私人定制与衣橱管理系统开发
2026/10/7 4:28:55 网站建设 项目流程

做毕设或者练手项目,最怕的就是题目看了半天,不知道到底要做什么。“Python flask微信小程序基于Android的服装私人定制私家衣橱APP”,这个标题信息量其实很大:后端用Flask,前端双平台——微信小程序加Android原生APP,业务方向是服装定制和个人衣橱管理。乍一看好像很杂,但它其实是一套非常标准的“后端API + 双端客户端”结构。这篇文章我就按我实际做这套系统的思路,从架构拆解、数据库设计、后端接口、双端实现到常见坑位,一条龙讲清楚,给后面要拿这个题目做参考的朋友一条可落地的路线。

先说明一下我的最终落地形态:Flask 2.x提供RESTful API,SQLite做本地开发验证、MySQL做生产环境;小程序端用原生微信小程序,覆盖登录、衣橱浏览、下单定制;Android端用Java + Retrofit + RecyclerView,覆盖同样的业务闭环。两个前端接口完全复用,后端只维护一套。我自己跑通后的project结构,后面你完全可以照搬。

1. 项目整体设计与架构思路

1.1 需求拆解:从题目看系统该有哪些功能

拿到这个标题,第一件事不是写代码,而是把“服装私人定制”和“私家衣橱”拆成两个大模块。

私家衣橱,本质是个人衣物资产库。用户要把自己的衣服录入系统,按季节、类型、穿着次数、购买时间打标签,可以随时翻看、筛选、删除。这里的核心诉求不是“商城”,而是“个人管理”。所以基本的增删改查、分类筛选、图片展示,一个都不能少。

服装私人定制,则是把“用户提出需求 -> 商家确认 -> 开始制作 -> 交付”这条业务线做通。用户不是直接买一件成品衣服,而是提交自己想要的款式、面料、尺寸、备注。于是需要一张定制订单表,里面要记录需求描述、状态流转、下单时间、预计完成时间。

把这两个模块拼起来,系统的边界就很清楚了:用户、衣物、分类、定制订单、订单项,再加上登录注册所需要的用户会话,一共五六张核心表就够。不要在初期把系统放大到库存、供应链、支付,不然一周都做不完。

1.2 架构选型:为什么是Flask + 小程序 + Android

为什么后端用Flask?因为这个项目的业务量级是典型的中小型应用,没有高并发、没有复杂消息队列。Flask足够轻,路由和请求处理清晰,配合SQLAlchemy做ORM,写起业务逻辑很快。对比FastAPI的话,FastAPI的异步性能更好,自带的OpenAPI文档对接口调试有帮助,但Flask生态更成熟,找资料特别容易,对毕设和演示来说,Flask反而更稳。

前端为什么双端?题目明确写了微信小程序和Android,说明要做的是多端覆盖。小程序胜在扫码就能用、不需要安装,适合给用户演示;Android原生APP则更适合体现在本地能力上的掌控感。双端共用一套后端API,正好把“一次编写接口,多端消费”的完整流程展示出来,这也是这类项目最有价值的加分点。

1.3 双端共存的通信设计

双端本身不直接通信,它们都只跟Flask后端交互。所有业务数据走HTTP JSON格式,文件图片用multipart/form-data上传。后端返回统一结构体,类似:

{ "code": 0, "message": "ok", "data": {} }

这样小程序和Android对响应解析是同一套逻辑,只是语言实现不同。Token用JWT,放进Header里由后端校验。两个客户端虽然在UI上独立,但业务规则和数据源完全统一,后面的联调测试也轻松很多。

1.4 目录结构规划

我实际做的时候,后端按照Flask的工厂模式组织:

flask_app/ ├── app.py # 应用入口、蓝图注册 ├── config.py # 配置 ├── models.py # 数据库模型 ├── decorators.py # JWT校验装饰器 ├── api/ │ ├── user_api.py # 登录注册 │ ├── wardrobe_api.py # 衣橱模块 │ └── order_api.py # 定制订单模块 ├── uploads/ # 图片保存目录 └── requirements.txt

小程序端单独目录,Android端单独目录,两者互不干扰。这个结构不是唯一的,但按照“后端一套,前端两个独立工程”的方式管理,后面扩展和答辩都不乱。

2. Flask后端:核心设计与接口实现

2.1 数据库设计:核心表结构与字段说明

数据库是整套系统的骨架。这个项目核心六张表,我逐个说。

用户表(user)要存openid、手机号、昵称、头像、性别、注册时间。openid用来对接微信小程序登录,手机号则用于Android端的注册登录。

衣物表(wardrobe_item)是衣橱核心,字段包括:用户id、衣物名称、分类id、图片URL、品牌、购买价格、购买日期、标签(文本)、穿着次数、创建时间。衣服的图片路径直接存相对URL,不要存base64,避免数据库爆炸。

分类表(category)就三个字段:分类名称、排序、创建时间。比如“上衣、裤装、裙装、外套、配饰”,少量数据可以预置,也可以在衣物录入时动态创建。

定制订单表(custom_order)是最复杂的,字段包括:订单编号、用户id、衣物名称、款式描述、面料选择、尺寸备注、定制要求、状态、下单时间、更新时间、预计完成时间。订单编号用“当前时间戳 + 用户id后四位”拼接,既好看又不会撞。

订单状态表可以不做单独表,直接在代码里定义枚举。如果要做商家端后台,再加一个admin角色字段在user表里就行。

这里要特别注意:衣物表的一个用户对应多条记录,订单表的一个用户对应多条记录,全部用外键关联。SQLAlchemy定义时设置db.ForeignKey,删除用户时要考虑级联删除(backref="...",cascade="all, delete-orphan"),不然会出现孤儿数据。

2.2 JWT用户认证与双端登录设计

登录是第一个要动的模块。微信小程序端用“code换取openid”模式,流程是——小程序调用wx.login()拿到code,把code发给后端,后端拿着code(再加上小程序AppID和Secret)去微信接口服务换取openid,然后后端自己生成JWT返回给小程序。这个方式调通了之后,用户在后续请求中带着JWT,后端就能识别是哪个用户。

Android端没有微信登录环境,就做成传统手机号加密码注册登录。注册时校验手机号格式、密码加盐哈希再存库,登录成功后同样返回JWT。这样两个前端都对接到同一个“登录成功 -> 获取Token”的逻辑上。

JWT在Flask里的实现不复杂,我用的PyJWT,发布时payload里放user_id和exp过期时间,密钥放在配置文件里。后端做一个装饰器@login_required,需要登录的接口加上它,请求头里取Authorization: Bearer <token>,校验成功就把当前用户对象塞进g.user。这一段代码是整个后端复用度最高的部分,一定先写稳。

2.3 衣橱衣物CRUD与图片上传

衣橱模块的接口就是标准的RESTful风格:

GET /api/wardrobe/list 获取用户衣物列表 GET /api/wardrobe/detail?id=1 获取单件详情 POST /api/wardrobe/add 添加衣物 POST /api/wardrobe/update 更新衣物信息 POST /api/wardrobe/delete 删除衣物 POST /api/wardrobe/upload 上传衣物图片

添加和更新都用POST,不用PUT/PATCH,是因为前端表单提交更简单,后端解析request.form和request.json时也好处理。列表接口支持分页参数page和pageSize,支持按分类、标签过滤。我的分页查询写法是这样:

page = max(int(request.args.get("page", 1)), 1) page_size = min(int(request.args.get("pageSize", 10)), 50) query = WardrobeItem.query.filter_by(user_id=g.user.id) if category_id: query = query.filter_by(category_id=category_id) total = query.count() items = query.order_by(WardrobeItem.created_at.desc()) \ .offset((page - 1) * page_size) \ .limit(page_size).all()

图片上传是很容易踩坑的点。Flask端接收request.files,保存到uploads目录下,文件名用时间戳加随机数重新生成,不要直接用用户原始文件名,避免中文乱码和重名覆盖。返回的路径以/uploads/xxx.jpg开头,客户端用“域名 + 该路径”拼完整URL访问。

2.4 定制订单状态机设计

定制模块核心是状态流转。我的订单状态定义为:

状态值含义流转方向
0待确认用户提交后等待商家确认
1定制中商家确认,开始量体制作
2已完成定制完成,待用户收货
3已收货用户确认收到
-1已取消用户或商家取消

用户提交定制订单走后端接口POST /api/order/create,生成状态0;商家(或者管理员)调用POST /api/order/update修改状态。用户端只允许取消未开始的订单(状态0),状态到1之后就不能取消,避免业务纠纷。在代码里我封装了一个change_order_status()函数,专门校验合法流转路径,非法操作直接返回400。

2.5 Flask部署与配置要点

Flask开发环境用app.run()没问题,但真要在手机上通过小程序调试,得让局域网内设备访问开发机IP。此时host="0.0.0.0",同时关闭debug模式,把SQLite的绝对路径配置好。生产部署建议Nginx反向代理 + Gunicorn,静态图片文件由Nginx直接服务,Flask只处理动态接口。数据库方面,SQLite适合开发和演示,上线就换MySQL,SQLAlchemy的模型定义几乎不用改,只需要修改配置里的连接串。

提示:小程序正式发布时要求后端必须HTTPS,而且域名要配置到小程序后台的request合法域名里。开发调试阶段可以在开发者工具里勾选“不校验合法域名”,但演示前一定确认后端服务和图片域名可访问。

3. 微信小程序端:从登录到衣橱展示

3.1 小程序登录与手机号获取流程

小程序端登录是整个前端工程的地基。微信小程序的授权登录分两层:第一层是用wx.login()拿到临时code,后端拿code换openid,创建会话;第二层才是手机号授权,wx.getPhoneNumber给用户弹窗确认后,可以在事件的回调里拿到加密数据,再交给后端解密获取真实手机号。

但这里有个很现实的坑:个人开发者的小程序大概率没权限申请getPhoneNumber接口,只有企业主体才能用。做毕业设计如果主体不满足,就直接用小程序的code登录作为唯一登录方式,不要死磕手机号授权。后端可以设计“注册时让用户选填手机号”,或者干脆等以后企业主体再补。

小程序里的会话保持我用的做法是:登录成功后把JWT存到wx.setStorageSync("token", token),然后在封装请求函数时统一带上Authorization头。这样所有页面不用重复处理token,改一个公共js文件就行。

3.2 衣橱首页:分类选择、卡片列表与加载更多

小程序首页是整个APP的门面。顶部放分类tab,下面放卡片式衣物列表,切换分类时重新请求列表。

分类tab我用的scroll-view加scroll-x="true"实现横向滚动,分类少的时候也可以直接用flex布局平均分。衣物卡片带图片、名称、标签、购买日期。图片用image组件的mode="aspectFill"裁剪填充,保证不同比例的照片都能统一视觉。

列表分页加载后,要在页面底部显示“没有更多了”,不然用户会一直上拉请求无意义数据。具体做法是onReachBottom事件里page++,然后新数据this.data.list.concat(res.data.list),如果返回的数据条数小于pageSize就设置hasMore=false。

这里要重点提醒:小程序页面渲染加载数据前会有白屏期,可以先给页面一个骨架屏或者loading状态。我在开发时是先wx.showLoading,数据返回后wx.hideLoading,不值得花太多时间做复杂骨架,但加载反馈一定要有。

3.3 衣物上传与定制需求表单

衣物上传是小程序里比较容易出错的模块,因为它涉及图片选择加文件上传两步。流程是:wx.chooseMedia让用户选图(支持拍照和相册),选完拿到临时文件路径,然后调用wx.uploadFile把文件传到后端上传接口。wx.uploadFile的formData里可以携带用户id和分类id,这样后端一次请求就能收到图片和基础字段。

定制需求表单和衣物上传类似,页面里用表单组件收集:衣物名称、选择面料(pickaer)、尺寸备注、款式描述、需求说明、上传参考图片。提交时把所有字段JSON序列化,调用订单创建接口。订单提交成功后,页面跳转到订单列表,并在订单列表显示“定制中”的状态标签。

给新手的一个建议:表单最好先做前端必填校验,比如衣物名称非空、尺寸备注必填,不要把所有校验都压给后端。前端校验过的数据到后端基本能直接入库,减少来回排查。

3.4 小程序样式适配与常见细节

小程序顶部导航栏在不同机型高度不一样:普通机型是64px,刘海屏会更高。开发时可以直接用wx.getSystemInfoSync()获取statusBarHeight,动态设置顶部栏占位高度,不要写死。底部tab栏的高度也会有差异,用tabBar的时候注意页面底部预留安全区。

另外列表页图片如果服务器返回路径是相对路径,image组件的src一定要拼上后端的域名前缀。我这边就是后端返回/uploads/1.jpg,小程序渲染时const imgUrl = baseUrl + res.data.data.imgUrl。这个坑特别隐蔽,接口调试都正常,但真机一跑图片全裂。

4. Android端:独立客户端的实现细节

4.1 网络层:Retrofit、OkHttp与统一响应封装

Android端我用的是Retrofit加OkHttp,这是目前最主流、资料最多的网络方案。第一步在build.gradle引入依赖,第二步定义统一的响应体类:

public class ApiResponse<T> { private int code; private String message; private T data; // getter/setter }

Retrofit接口里全部返回Call<ApiResponse<Xxx>>。后端返回结构统一,Java泛型就能自动解析data。Retrofit配合Gson转换器,JSON字段名命名保持和Java字段一致,用@SerializedName处理后端字段如果带了_(比如created_at)的情况。

网络请求里要做统一的异常处理。服务器连接失败、Token过期、业务错误都封装成一个回调,避免每个网络请求都写一大段try-catch。Token过期时自动跳转登录页,这个逻辑放在OkHttp的拦截器里面实现,比散落在每个请求里可靠得多。

4.2 登录注册界面与Token持久化

Android端是传统的手机号密码登录。页面用两个EditText加一个登录按钮,注册入口放登录页右侧。初次进入App时先检查本地有没有Token,如果有就直接跳主页面,没有就留在登录页。这个判断逻辑在SplashActivity里做,不给用户多余的点击操作。

Token用SharedPreferences存,键名保持统一。网络请求时通过OkHttp拦截器统一添加Authorization头,所有需要登录的接口就不用重复写认证参数。退出登录时清空SharedPreferences并跳转登录页,同时要清空内存中的用户对象,避免页面栈里的其他页面拿到脏数据。

4.3 衣橱列表:RecyclerView、加载更多与Glide图片加载

衣橱列表在Android端用RecyclerView加LinearLayoutManager,图片用Glide加载。Glide处理URL图片时如果网络图加载失败,要加.placeholder()和.error()占位图,不然显示空白。列表底部用一个footer item显示加载状态:加载中显示ProgressBar,到底显示“没有更多了”。

加载更多我用的是RecyclerView的滑动监听——倒数第二个item可见时就触发下一页请求,同时加isLoading标志位防止连续触发重复请求。这里有个细节:第一次进入页面时加载第一页,如果用户连续滑动很容易重复请求,加个标志位能挡掉大部分无效请求。

4.4 图片选择与上传进度条

Android端从系统选择照片用的是系统Photo Picker或者Intent调起相册,拿到图片URI后转成文件路径再上传。这里有个版本相关的坑:Android 11以上对文件路径读取限制很严,不能直接通过File的方式访问所有外部存储图片。我的做法是用ActivityResultContracts.PickVisualMedia这个新API调起系统图片选择器,同时用ContentResolver读取图片输入流,拷贝到应用私有目录后再上传,从根上避开权限适配问题。

上传图片用OkHttp的RequestBody上传sdcard不可靠的那套已经过时了,直接用MultipartBody加文件流。上传进度用RequestBody的监听器实时回调,更新到页面上的ProgressBar。好好的进度条还能起到“安抚等待心情”的作用,衣服图片一般不大,但进度体验一定要有。

4.5 Android真机适配与权限处理

Android 6以上要动态申请权限,尤其读写存储的权限。但Android 10以上分区存储后,READ_EXTERNAL_STORAGE的用途受限,用系统Photo Picker就不会遇到权限问题,这点一定是写Android端时优先采纳的方案,不要再用老一套存储权限申请逻辑。

另外Android的UI分辨率碎片化比较严重,布局建议多用wrap_content加match_parent,少用writing死dp尺寸。我自己的经验是:手机宽度在360dp到400dp之间最普及,页面左边距统一用16dp,字体大小不小于14sp,这样可以保证大多数真机不会出现大的布局偏差。

5. 定制订单全流程联调

5.1 从提交定制需求到订单确认的完整链路

以小程序端下单为例,完整链路是这样的:用户A在定制页面填写“白色棉质衬衫、长袖、修身版型、胸围96、腰围80”,上传参考图,点击提交。小程序把所有表单字段包装成JSON,请求POST /api/order/create。后端把订单写入custom_order表,状态为0,返回订单编号。

之后用户和商家(后台)都能看到这个订单。商家点确认,调用订单更新接口,状态从0变成1。小程序端通过下拉刷新或者轮询看到订单状态更新,页面显示“定制中,预计X月X日完成”。定制完成发货后状态变成2,用户点收货变成3,这个闭环就是一个完整业务演示。

5.2 双端共用一套订单数据的处理思路

因为小程序和Android共用同一个Flask后端,所以只要后端接口签约定得清晰,两端看到的订单数据天然是一致的。Android端管理衣橱、小程序端下单、然后在Android端看订单状态,完全可行。关键是后端接口对两个端不区别对待,统一用JWT识别用户身份,谁带Token谁就是用户本人。

这里要着重注意时间格式的统一。后端返回时间如果是datetime对象,JSON序列化得到的是"2025-05-01T12:00:00",但小程序和Android的日期格式化方式不同。我的建议是后端统一转成"yyyy-MM-dd HH:mm:ss"字符串返回,两端直接展示,不用各自再解析。

5.3 联调测试的模拟数据设计

联调过程中没有真实订单和衣物数据的时候,可以写一个批量模拟数据脚本。后端用SQLAlchemy批量往数据库灌十条衣物、十条订单、五个分类。模拟数据不要太随便,要有不同的分类、状态和标签,这样双端联调翻看列表的时候才能验证到筛选、状态标签、空数据兜底效果。演示前我会把模拟数据重新清库再导入,保证演示现场干净整洁。

6. 常见问题与排查技巧实录

6.1 小程序真机预览无法上传图片

真机预览上传图片失败,大部分情况下是后端调用域名没有配置到小程序后台的downloadFile合法域名或者不校验域名没勾选。另一个常见原因是wx.uploadFile里的name参数要跟后端request.files.get("file")一致,不一致后端根本取不到文件。我试过改接口联调时前后端变量名不一致,排查了半天才发现。前端写file,后端也写file,约定好就别动。

6.2 Android 10+文件路径读取失败

Android升级分区存储后,/storage/emulated/0/...路径在没申请对应权限时是读不了的。这个问题一搜一大把,原因是新版系统的存储访问模型变了。解决办法就是走系统Photo Picker,拿到URI之后用ContentResolver转为输入流,再保存到应用自己的缓存目录。我从Android 10适配到Android 14都是这个流程,稳得很。

6.3 Flask跨域与请求体过大

后端Flask如果不处理跨域,小程序和Android发请求时,浏览器访问API还好说,但小程序或某些网络库会直接拦截跨域响应。用flask-cors包统一开启就行:

from flask_cors import CORS CORS(app)

另一个坑是Flask默认表单和JSON请求体大小有限制。如果用户上传很大的图片,会收到413 Request Entity Too Large。在后端初始化时设置app.config["MAX_CONTENT_LENGTH"] = 16 * 1024 * 1024,16MB对衣服图片来说足够了。客户端上传前本地也做大小压缩,防止大图浪费流量。

提示:小程序上传图片之前,用wx.compressImage压缩一次,Android端用BitmapFactory加采样率压缩,双端都把图片大小控制在1MB以内,后端和真机预览的体验都会顺畅很多。

6.4 图片在双端显示不一致

同一张图片在小程序端正常显示、在Android端却加载不出来,最常遇见的是HTTPS证书问题。Android端OkHttp对自签名证书默认不信任,即使浏览器访问没提示。解决方式有两个:生产环境换正规证书;开发阶段在OkHttp的Client里配置信任所有证书。不要在新手期花太多时间折腾证书,本地调试直接信任所有证书最快,上线前再换正式证书。

6.5 SQLite并发写锁与MySQL切换

Flask本地开发时SQLite LITE会偶发database is locked,这是SQLite本身的写锁限制,多个请求同时写库时比较常见。如果只是毕设演示,这个频率通常很低。但一旦演示现场出现这个报错会非常尴尬,我建议后端开发阶段就切MySQL(或者Docker起一个MySQL容器)。SQLAlchemy模型不用改,只要配置文件切换数据库连接串,问题立刻消失。

7. 一点实操体会

整套系统做下来,最大的感受是:项目成功的关键不在某个端写得多么酷炫,而在于后端接口契约定得够不够稳定。只要Flask的返回结构统一、JWT认证逻辑清晰、数据库表之间关联合理,小程序端和Android端基本是平行推进的,不会互相拖后腿。

如果你准备拿这个题目做毕设或者练习,我的建议是先花两天时间,只做三件事:画清楚数据库表关系、定好全部接口文档、把JWT登录跑通。这三件事做完,整个项目的地基就稳了,后面做双端时基本就是按接口填页面。而千万不要一上来就打开Android Studio画界面,或者在小程序里调样式,那样很容易陷入“前端写得热闹,后端一坨浆糊”的局面。

最后分享一个调试小技巧:在Flask后端配一个全局请求日志装饰器,把每个请求的URL、参数、耗时、返回码都打印到终端。双端联调时看到日志就相当于同时看到了两个客户端的所有动作,定位问题是效率最高的,没有之一。动手做吧,这个项目没有想象中那么复杂。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询