ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于NetCore与原生微信小程序搭建商城系统:架构设计与实践指南

基于NetCore与原生微信小程序搭建商城系统:架构设计与实践指南 简介在移动电商快速发展的今天小程序商城成为企业触达用户的重要渠道。技术选型直接影响开发效率与系统稳定性。本文从商城系统后端架构切入对比原生微信小程序与跨端框架的适用场景分析.Net Core作为API服务层的技术优势。围绕项目分层、统一接口设计、缓存策略、微信支付回调等核心环节结合C#工程实践梳理了从开发到上线全流程的关键问题与解决方案。无论是准备从零搭建小程序商城还是优化现有后端服务本文都能提供可落地的参考思路。 做了几年.Net后端一直想把手里的老商城系统搬到微信小程序上。前后折腾了三个多月把一套基于原生微信小程序和NetCore的商城从零搭到了上线。这中间踩过的坑、推翻过的设计、最后沉淀下来的方案我觉得值得写出来。如果你也在纠结小程序商城到底怎么选技术栈原生和跨端框架到底选哪个NetCore做后端接口有没有什么坑这篇应该对你有用。出发点很简单团队主力是C#手里有一套已经跑了两年的B端订单系统底层订单、库存、支付回调这些逻辑都是现成的。老板说要做一个微信小程序商城第一反应绝对不是换语言重写而是想清楚怎么把这套.Net的能力平滑延伸到小程序端。1. 为什么最后选了原生微信小程序 NetCore这套组合先交代一下当时面临的几个选项以及各自的取舍。这个决策直接决定了后面所有的开发路径。1.1 跨端框架和原生小程序之间的摇摆团队最开始不是没想过用uni-app或者Taro。这两套框架在技术社区里确实呼声很高一套代码同时输出小程序、H5、App听起来非常诱人。但我们实际评估下来有几个问题首先我们已有的核心资产是后端逻辑不是前端界面。商城涉及的移动端页面不多满打满算就首页、分类、商品详情、购物车、订单列表、结算页、个人中心这几大块。为了这几个页面引入一套跨端框架还要额外维护一套编译链路性价比不高。其次原生小程序的开发和调试体验其实比想象中好。微信开发者工具虽然偶尔抽风但它对原生页面的支持永远是最及时的。尤其涉及到微信支付、订阅消息、手机号快捷验证这类强微信依赖的能力原生方式对接最直接不需要等第三方框架去适配微信的基础库更新。最后也是最重要的我们后端是C#如果前端再引入一套带着Node构建链路的框架整个团队的技术栈就从单一语言变成了C# JavaScript Node构建工具三条线。这对一个不到十人的小团队来说招聘成本和维护成本都会上升。1.2 NetCore在这里面的角色定位NetCore在这套系统里不是替代品而是一个承上启下的连接层。我们原来的订单系统是.Net Framework 4.7.2数据库是SQL Server内部服务之间用的是WCF。小程序这种面向公网的场景WCF显然不合适所以我们在NetCore里重新实现了一套面向移动端的API层直接对接原有数据库和核心业务逻辑。选NetCore而不是继续用.Net Framework有一个很现实的理由小程序要求所有请求必须走HTTPS而NetCore在跨平台部署、Kestrel性能、依赖注入、中间件管道的设计上比老Framework更适合做这种面向公网的轻API层。尤其在后端要同时支撑微信支付回调、微信登录态换取、模板消息推送这几个需要高并发响应的场景时NetCore的异步模型顺手得多。1.3 这套组合的适用人群如果你的团队情况符合下面几条我建议认真考虑这套组合后端主力是C#/.Net不愿意为了小程序单独引入一套Java或Node服务现有业务已经在SQL Server或MySQL里沉淀了完整的商品、订单、库存数据商城功能以标准的展示、下单、支付、物流为主不需要特别复杂的富交互希望能控制整条技术链路不依赖第三方BaaS平台反过来如果你的核心诉求是两周出一个Demo去融资或者完全没有后端团队那直接上微信云开发可能更现实。技术选型这事没有银弹先想清楚自己有什么再选工具。2. 后端工程搭建NetCore下的分层结构与核心API设计这一节直接讲后端怎么从空项目变成一个能扛住小程序业务的API服务。我不会贴完整代码重点讲结构设计、关键接口的思考和几个容易被忽略的细节。2.1 项目分层别把Controller写成大泥球商城后端看起来简单无非是商品查询、用户登录、下单支付。但一旦你把所有逻辑都塞进Controller后面每加一个功能都是噩梦。我的分层方式是这样的ZhaoShop.Api // API层Controller、DTO、过滤器 ZhaoShop.Application // 应用层业务用例、命令/查询处理核心业务编排 ZhaoShop.Domain // 领域层实体、值对象、领域服务 ZhaoShop.Infrastructure // 基础设施EF Core DbContext、仓储实现、外部服务调用 ZhaoShop.Shared // 公共层常量、扩展方法、通用结果包装这里有一个容易被忽视的点DTO数据传输对象一定要和实体分开。我在这个项目里吃过亏。刚开始图省事直接把商品实体丢给前端结果多返回了不少冗余字段不说有一次重构数据库字段直接把小程序端搞崩了。后来老老实实为每一个接口定义了显式的DTO虽然代码量上来了但接口的稳定性高了一个量级。2.2 API设计RESTful还是RPC风格商城接口我建议别太纠结RESTful的教条实用为主。微信小程序端的请求方式非常集中绝大部分场景就三个GET查列表/详情、POST提交订单/支付、PUT更新状态。我们的接口风格大概是这样功能模块请求方式和路径说明商品列表GET /api/v1/products?categoryIdxxxpage1size10分页加筛选商品详情GET /api/v1/products/{id}返回详情和SKU提交订单POST /api/v1/orders幂等键放到Header里订单列表GET /api/v1/orders?statuspending按状态过滤取消订单PUT /api/v1/orders/{id}/cancel状态变更走PUT微信登录POST /api/v1/auth/wxlogin用code换token统一返回值这块我们封装了一个ApiResultTpublic class ApiResultT { public int Code { get; set; } public string Message { get; set; } string.Empty; public T? Data { get; set; } public bool Success Code 0; public static ApiResultT Ok(T data) new() { Code 0, Data data }; public static ApiResultT Fail(int code, string message) new() { Code code, Message message }; }所有接口都返回这个统一结构小程序端封装的request函数只需要判断Code 0逻辑就非常清爽了。注意这里业务错误码和HTTP状态码是分开的。HTTP 200只是表示请求到了后端具体业务是否成功看Code。2.3 C#里的字符串和拼装问题一个小坑做商品详情页时经常需要把一组SKU属性拼成前端需要的JSON结构。比如颜色红色尺寸XL。这个拼接逻辑里C#开发者最容易犯的错就是用循环拼字符串。在小程序商城这种移动端接口里虽然单次拼接的数据量不大但QPS一上来GC压力就上来了。后来我在Shared层写了一个通用的扩展方法用StringBuilder来处理这类拼接逻辑public static string ToSkuDescription(this IEnumerableProductSku skus) { var sb new StringBuilder(); foreach (var sku in skus) { sb.Append(${sku.AttributeName}{sku.AttributeValue}); } return sb.ToString().TrimEnd(); }这是一个很小的点但对C#新人来说理解StringBuilder和string的区别很有价值——字符串是不可变对象每次用拼接都会产生新的字符串对象循环里这么干是典型的性能浪费。2.4 定时任务用NetCore内置逻辑处理订单超时商城有一个经典的业务需求订单超过30分钟未支付就自动取消。这个需求在小程序端看起来很简单但后端实现方式会直接影响系统稳定性。第一版方案用的是Timer在API进程里跑一个后台服务每分钟扫描一次超时订单。后来发现一个问题如果你部署了多个实例负载均衡每个实例都会跑这个扫描任务就会重复处理同一个订单。要解决这个要么用一个分布式锁要么引入Redis的SETNX。如果你用NetCore的BackgroundService代码很简洁public class OrderTimeoutBackgroundService : BackgroundService { private readonly IServiceProvider _services; private readonly TimeSpan _period TimeSpan.FromMinutes(1); public OrderTimeoutBackgroundService(IServiceProvider services) { _services services; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { using var timer new PeriodicTimer(_period); while (!stoppingToken.IsCancellationRequested) { await using var scope _services.CreateAsyncScope(); var orderRepo scope.ServiceProvider.GetRequiredServiceIOrderRepository(); await orderRepo.CancelExpiredOrdersAsync(); await timer.WaitForNextTickAsync(stoppingToken); } } }这个方案适合中小商城。如果订单量极端大或者你已经有分布式任务调度平台直接上那个更省心。2.5 微信登录态的Server端实现小程序的登录不是传统意义上的用户名密码而是基于微信的wx.login获取临时code然后后端拿code去微信服务器换openid。这里有一个容易出错的地方code只能使用一次而且有效期只有五分钟。我们第一次联调时没注意在业务中间环节不小心重复使用code导致登录偶发失败问题还很难排查。正确的做法是小程序端调用wx.login获取code后端收到code后通过https://api.weixin.qq.com/sns/jscode2session交换openid和session_key后端用openid到数据库找用户找不到就自动注册一个生成自己的登录态token我们用的是JWT返回给小程序小程序把token存在本地后续所有请求都带上JWT这块要特别提醒不要把敏感信息放进去JWT是base64编码的不是加密的。有人把手机号、地址这种数据直接塞进token这是很不安全的。3. 小程序前端骨架页面结构、状态管理与登录态后端搭好了前端这片反而容易被人低估。原生微信小程序看起来简单但真正把一个商城塞进去页面结构、数据流、组件通信、分包策略处处都是讲究。3.1 页面目录是怎么组织的先看我们的目录结构这个结构不是随便拍的每层都有它的职责pages/ index/ # 首页 category/ # 分类页 product/ # 商品详情 cart/ # 购物车 order/ # 订单结算和列表 user/ # 个人中心 components/ product-card/ # 商品卡片 sku-selector/ # SKU选择弹窗 empty-state/ # 空状态占位 utils/ request.js # 网络请求封装 auth.js # 登录态管理 format.js # 价格、时间格式化 app.js app.json app.wxss关于分包我需要多说几句。如果你的商城商品图多、页面多主包限制2M这件事迟早会卡住你。我们的做法是把首页、公共组件这些核心路径留在主包把商品详情、订单中心、售后这些低频页面放到分包里。小程序启动时会先下载主包等用户进入某个分包再按需下载体验会好很多。3.2 Request封装别每次写一堆重复代码原生小程序没有axioswx.request的API又比较原始。所以我封装了一个utils/request.js核心逻辑是这样的const request (url, method, data) { return new Promise((resolve, reject) { wx.request({ url: ${BASE_URL}${url}, method, data, header: { Content-Type: application/json, Authorization: Bearer ${getToken()} }, success(res) { // 这里统一处理业务错误码 if (res.data.code 0) { resolve(res.data.data); } else if (res.data.code 401) { // token过期跳转登录 reLogin().then(() { // 重新请求 }); } else { wx.showToast({ title: res.data.message, icon: none }); reject(res.data); } }, fail(err) { wx.showToast({ title: 网络异常请稍后重试, icon: none }); reject(err); } }); }); }; module.exports { get(url, params) { return request(url, GET, params); }, post(url, data) { return request(url, POST, data); }, put(url, data) { return request(url, PUT, data); } };这里有一个值得注意的点401统一处理时不能直接跳转要处理好并发。比如用户在一个页面同时发出三个请求三个都返回401如果每个请求都触发一次重新登录就会产生多次登录请求。我的做法是加了一个isRelogin标志登录过程中其他请求排队等待。3.3 登录态同步不是setStorage就完事了小程序端登录一个很常见的错误是wx.login拿到code后直接存到Storage里然后在后续请求里把code当token用。这是完全错误的。code是换取token的临时凭证不是身份凭证。正确流程是async function login() { const { code } await wx.login(); const res await request.post(/auth/wxlogin, { code }); // res里面是后端返回的token和用户基本信息 wx.setStorageSync(token, res.token); wx.setStorageSync(userInfo, res.userInfo); }还有一点如果用了自定义登录态一定要在app.js的onLaunch里做一次静默登录。但这里有个坑wx.login是异步的如果页面在登录完成前就发请求就会出现401。所以我做了一个极简的登录中等待队列——登录完成前业务请求全部挂起完成后依次放行。3.4 SKU选择器商城页面里最容易被低估的组件商品详情页的SKU选择器难度其实被严重低估了。用户选择红色后XL可能就不可选了这是典型的SKU库存矩阵问题。如果后端只是返回了所有商品SKU列表前端需要在内存里做一次组合查询。我的做法是后端返回一个skuMapkey是颜色:尺寸的组合value是库存。前端选择时通过遍历所有可能组合来判断每个选项是否可点击。这一步如果用Object和数组的some、every方法做逻辑很清晰但一定要控制好循环的复杂度SKU维度一多这种组合数量是乘数级的。实测下来普通服装商品的SKU维度一般在2-3个前端做全量判断完全撑得住。但如果你的商品有4个以上维度建议直接把库存矩阵的可用组合返回给前端让前端做索引匹配否则数据量会很大。4. 订单流程联调缓存、库存扣减与支付回调订单环节是商城系统最容易出问题的地方。前端可能觉得我调用了下单接口订单建好就行了但后端要处理一连串的问题库存够不够、价格变了没有、支付回调什么时候才到、超时未支付怎么办。这一节我详细讲讲我们是怎么把这条链路调顺的。4.1 下单接口的后端处理顺序我们下单接口的后端处理逻辑是这样的顺序很重要校验用户登录态和请求参数从Redis里查一下当前商品是否还有库存。这里用的不是数据库是Redis的预扣库存创建订单主记录和订单明细记录异步把用户下单的幂等键存到Redis防止重复下单返回订单id和支付参数给小程序端这里为什么要引入Redis因为下单接口是整个商城里QPS最高的接口之一如果每一次下单都直接查数据库、锁行、更新库存数据库压力会非常大。而Redis的单线程模型天然适合做扣减库存这种原子操作。一个比较简化的库存扣减代码如下public async Taskbool TryDeductStockAsync(int skuId, int quantity) { var key $stock:sku:{skuId}; var current await _redis.HashIncrementAsync(key, locked, -quantity); if (current 0) { // 库存不足加回去 await _redis.HashIncrementAsync(key, locked, quantity); return false; } return true; }RedLock这种方案我没有用因为商城这种场景对一致性要求没有到那个级别。在单体应用下直接调Redis的INCR/DECR就够了复杂分布式锁带来的维护成本远大于收益。4.2 支付回调易被测试环境骗了的问题微信支付的回调是异步的服务器要先返回success给微信微信才会停止重试。这个逻辑本身不复杂但有几个坑第一个坑回调处理一定要做幂等。微信官方声明回调可能会到达多次。比如网络抖动后重试你的回调接口可能被重复请求。如果每次回调都执行一遍更新订单状态扣减库存发送模板消息订单就可能被重复处理。我们的做法是在回调处理入口先查一下订单状态如果已经是已支付直接返回成功不再重复处理。第二个坑验签。回调内容里有sign字段你必须要用微信支付平台的公钥做验签确认这个请求真的是微信发来的不是别人伪造的。有的开发者为了省事跳过了这一步结果被刷接口订单全部变成已支付商品被免费拿走这是真实发生过的事。第三个坑回调处理要快。微信对回调响应时间是有限制的超时会被中断并重试。如果业务逻辑太复杂导致处理时间过长可以先把回调信息和订单状态存到数据库返回success再用后台任务去处理后续业务。这个模式叫先落库、后处理。4.3 SignalR商城里的实时通知怎么玩做这个项目的时候我还接了一个SignalR的场景用户下单支付成功后商家后台的电脑端也是.Net系可以实时收到新订单提醒不用不断刷新页面。SignalR在NetCore里属于开箱即用的东西。但要注意小程序端的wx.connectSocket不能直接连SignalR的WebSocket。SignalR的协议比原生WebSocket复杂客户端必须用SignalR的JS客户端库。在小程序里这不是直接能用的需要做一个适配层。最终我们没有强上SignalR的服务端推送到小程序端而是走了变通方案商家后台网页用SignalR实时收新订单通知小程序端通过订阅消息模板消息接收订单状态变更通知这个方案在技术复杂度上是合理的商家后台是桌面网页用SignalR浏览器支持很好小程序端用微信订阅消息本来就是这个场景的标准解法。如果你非要在小程序端做实时推送也不是不行但要么引入第三方推送服务要么自己封装SignalR小程序客户端成本都不小。4.4 小程序端webview和本地页面的选择商品详情、订单详情这种长页面有时候运营希望用富文本编辑直接塞一大段文章进去。我们最开始的做法是把富文本内容原样渲染到小程序里用rich-text组件。但这个组件对视频、复杂表格支持不好后来干脆对运营后台的内容做了一层判断如果是简单的富文本用rich-text如果运营上传的是自定义H5页面就放到webview里展示。这里要提醒一下小程序里的webview有域名白名单限制必须在小程序管理后台配置业务域名而且需要校验文件。我们在集成时就在这里卡了一天因为业务域名的校验文件一直没放到服务器根目录。5. 上线部署与联调排错从本地到线上的远程链路后端写完、小程序写完之后真正的战斗才刚刚开始。部署、网络、证书、并发问题、小程序的审核规则这些在生产环境才会暴露出来的问题我整理成几个最典型的坑。5.1 IIS和Docker我们选了哪条路我们的生产环境跑在Windows Server上历史系统都是IIS。NetCore应用部署到IIS有两种方式一种是进程外托管即Kestrel监听一个本地端口IIS做反向代理一种是进程内托管IIS直接托管NetCore应用。我在旧服务器上用的是进程外托管Kestrel监听一个不对外暴露的端口IIS对外监听443端口然后反向代理到Kestrel。这里有一个必须注意的点小程序要求所有请求域名必须是HTTPS而且ICP备案的域名必须在小程序后台的request合法域名里配置。这个配置不是即时的修改后大概几分钟生效但如果你改了域名白名单却忘了在服务器上放校验文件会一直报不在以下合法域名列表中。Docker我们没用原因是历史包袱太多SQL Server和第三方的OCR组件都装在Windows上容器化迁移成本高。但如果你是从头搭的新项目我很建议用Docker至少在环境一致性上会省很多心。5.2 小程序白屏问题看起来像前端问题实际是接口问题热搜词里有个uniapp做微信小程序在手机上预览没问题但是在微信开发者工具上是白片这个我深有感触。我们上线前也遇到过类似的在开发者工具里一切正常真机预览却白屏。排查思路是这样的真机上打开调试模式看Console报错结果发现是某个接口请求失败导致页面渲染时productList是undefined取productList.length直接抛异常为什么开发者工具正常而真机失败因为开发者工具本地环境走了代理真机的请求环境是线上域名没走通这类问题本质上是前后端联调不彻底模拟环境掩盖了问题。给所有做商城的同行一个建议真实环境的自测不能少至少要在体验版里完整走一遍首页 - 商品详情 - 加购物车 - 结算 - 支付 - 查看订单全流程。这个流程走下来能暴露一半以上的上线问题。5.3 C#读取Step模型文件和打印机状态这类需求别混进来这个提醒可能有点奇怪但确实现实中会碰到。项目进行到后期总有业务方提一些加个小功能的需求。热搜词里有一堆C#处理硬件、读取Step模型文件的东西——如果做商城系统这类需求一定要明确边界它们不适合塞进商城的API服务里。原因是商城系统的核心是交易链路稳定你用同一个服务进程去处理一个需要大量CPU计算的文件解析任务一旦这个任务失控会把整个API的线程池吃掉用户的正常下单请求也会被拖垮。正确做法是拆成独立任务服务或者走消息队列异步处理。5.4 小程序端文章富文本、短剧视频这种非商城需求怎么处理热搜词里还提到了微信小程序短剧和视频播放。商城做了几个月后运营也会想加内容模块比如商品宣传短剧、短视频推广。这里最大的坑就是层级问题——很多安卓手机尤其是三星部分型号video组件会强制置顶遮挡住弹窗和自定义组件这是一个无解的兼容问题。最稳妥的方案是把这类内容放到独立的webview页面里用H5的video标签播放而不是在原生小程序页面里直接塞video组件。6. 商城系统的性能细节缓存、并发与C#常见问题最后一节梳理几个跟C#和NetCore性能相关的小细节。这些点未必会在功能测试阶段暴露但线上流量一起来它们会慢慢浮出水面。6.1 缓存穿透、击穿、雪崩小商城也有大压力商品详情页是最容易被频繁请求的。如果每个用户访问详情页都直接查数据库大促时QPS很容易被打爆。常规做法是加一层Redis缓存缓存穿透请求一个不存在的商品id每次都打到数据库。解决办法查不到结果也缓存一个空对象并设置短过期时间。缓存击穿某个热点商品的缓存过期了瞬间大量请求打到数据库。解决办法在更新缓存时加互斥锁或者让过期时间带上随机值。缓存雪崩大量缓存同时过期数据库压力剧增。解决办法过期时间加上随机偏移避免同一时刻大面积失效。这三种问题在C#里的处理方式都成熟我推荐用IDistributedCache接口抽象后面换Redis或内存缓存都方便。6.2 .NET C# 无法加载一个或多个请求的类型这个热搜词对应的错误信息我在这项目里遇到过而且是在部署到IIS后才出现的。错误提示是无法加载一个或多个请求的类型。有关更多信息请检索 LoaderExceptions 属性。这个问题的根因往往是程序集版本冲突或缺少依赖的DLL。比如你引用了某个NuGet包的3.1.0版本但生产环境的bin目录里还残留着旧版的同名DLL。我们用了一个方法就是在错误码里捕获ReflectionTypeLoadException然后把LoaderExceptions里的每个错误详情打到日志里catch (ReflectionTypeLoadException ex) { foreach (var loaderEx in ex.LoaderExceptions) { _logger.LogError(loaderEx, 程序集加载失败: {Message}, loaderEx?.Message); } }日志打出来后基本都是未能加载文件或程序集XXX系统找不到指定的文件然后去NuGet把对应版本拉回来就好了。这类问题有很强的环境相关性本地正常不代表服务器正常部署后第一件事应该是把详细的启动日志落盘。6.3 定时任务和Timer的调度别用Thread.Sleep如果你在NetCore里写后台任务完全不建议用Thread.Sleep做循环调度。它不仅浪费线程资源而且在服务停止时无法优雅退出。用BackgroundService配合PeriodicTimer是更干净的模式前面订单超时任务已经给了示例。如果任务需要在多实例部署下只跑一次建议引入一个简单的分布式锁或者用数据库的锁表记录来实现。6.4 C# SignalR在业务里的真实使用体验虽然小程序端没有强上SignalR但商家后台的实时通知这块我们确实用了用下来的体验是很好的。NetCore的SignalR跟老的WebSocket封装比最大的优势是自带重连、心跳和分组。做后台通知时一个用户可能开了多个标签页SignalR可以按用户分组把消息推送到该用户的所有连接上。部署时要注意SignalR默认不走普通HTTP的负载均衡如果你用了多实例部署的负载均衡需要开启Redis Backplane否则消息只会推送到其中一台服务器上其他实例的连接收不到通知。6.5 数据库操作用EF Core还是Dapper商城系统涉及大量复杂查询比如订单列表的各种筛选条件、商品列表的多条件排序这类场景如果用EF Core表达式树的写法虽然优雅但性能调优起来比较麻烦。我们最终采用了混合方案常规的CRUD用EF Core复杂的统计和动态查询用Dapper。为什么用Dapper因为它轻量、性能接近原生ADO.NET而且SQL直接可控。比如根据多个可选条件筛选订单这种用EF Core拼接条件虽然也可以但生成的SQL不可控一旦加了索引字段查询计划可能走偏。Dapper里直接写SQL配合DynamicParameters性能问题一目了然。7. 想清楚你的边界再动手写代码这个项目整体做下来我最大的体会是技术选型没有绝对的对错只有合不合适。原生微信小程序加NetCore这套组合对一支以C#为主力的小团队来说是一条性价比很高的技术路径——后端能复用大量已有资产前端不用引入重型框架整个链路可控性很强。但它的短板也需要心里有数原生小程序的UI开发效率确实不如Web前端复杂的交互动效需要投入更多精力NetCore生态虽然越来越成熟但和Java的电商解决方案比开箱即用的东西还是少一些。如果你在做一个需要快速试错、大量A/B测试的商城这套组合可能会让你觉得太慢了。最后再分享一点我的个人习惯上线前一定要把后端日志和小程序端的错误日志打通。用户在前端点了个按钮后端报了什么错最好能在一个平台里同时看到。我们用的是NLog写到数据库同时小程序端用wx.getRealtimeLogManager上报前端错误这样排查问题的时候不用两边来回翻省了非常多的时间。这套东西做完之后后面再去接小程序商城、外卖小程序、预约小程序骨架都是可以复用的。核心API的认证方式、统一返回结构、错误处理链路、资源访问权限这些东西一旦沉淀成模板新开一个项目就是填页面 配数据库的活了。如果你也在用C#和NetCore做小程序类项目想进一步交流细节欢迎在评论区或者私信里聊聊踩过的坑。毕竟这类经验自己啃是真的费头发。本文还有配套的精品资源点击获取
返回列表