news 2026/10/18 8:19:30

PHP+小程序+APP:活动型文创商城系统全流程设计与实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP+小程序+APP:活动型文创商城系统全流程设计与实践

做垂直电商系统这几年,接触过不少“短平快”的需求。最近接到的这个项目印象很深:一套围绕红色文物活动场景的文创产品商城系统,后端用 PHP,客户端要覆盖微信小程序,同时还要出一个 APP 端。项目代号是“2fil7831”,不管代号怎么变,业务内核其实很典型——活动内容展示、文创商品在线销售、微信支付、订单管理、线下核销,一套中小型垂直商城该有的环节它全占了。

这类项目的甲方通常是文化活动组织方、场馆运营方或相关展陈单位。他们的核心诉求不是做一个“大而全”的电商平台,而是要一个能跟着活动节奏走、上线快、维护简单的系统。活动开始前能开售商品,活动期间能承接集中的下单峰值,活动结束后能快速导出数据做结算。对这个场景来说,技术选型不需要炫技,稳和快才是第一位的。这篇文章就把整个项目从方案设计、数据库建模,到后端接口、小程序、APP 实现,再到上线前后踩过的坑,完整捋一遍。想接同类项目或者需要参考的朋友,可以直接拿来对照着做。

1. 项目整体设计与方案选型

1.1 需求拆解:活动型文创商城到底要解决什么问题

先别急着建表写接口,项目启动第一件事是把“这个商城和普通商城不一样在哪”搞清楚。红色文物活动类的文创商城,本质上是为一场或一系列主题文化活动服务的,商品围绕文物、历史、纪念主题展开,比如纪念徽章、书籍画册、文具、工艺摆件、文化衫这些。

这种模式有个显著特点:时效性非常强。活动有明确的开始和结束时间,商品跟着活动走,活动结束商品基本就下架了。这和常年经营的常规商城差别很大,对商品生命周期管理、活动状态控制、库存限量管理都有特殊要求。

从用户角色角度看,系统至少涉及三类人:

  • C 端普通用户:浏览活动内容、查看商品详情、下单支付、查看订单、到现场出示提货码。
  • B 端运营管理员:配置活动信息、上下架商品、管理规格库存、处理订单发货、扫码核销。
  • 超管或财务:查看销售数据、导出报表、处理退款。

核心流程主要有三条:

  1. 用户看到活动内容(图文、视频、展讯),进入文创商城浏览商品。
  2. 选择规格(比如铜质/银质、标准版/精装版),下单并完成微信支付。
  3. 运营端收到订单,选择快递发货或者现场自提核销,用户确认收货,整单完成。

拆完需求基本可以得出结论:这个系统不需要复杂的社交裂变,不需要分销体系,也不需要社区问答。真正要打磨的是商品管理、活动上下架、订单状态机和库存并发控制这四条主线。把这个圈定清楚了,后面开发才不会跑偏。

1.2 技术选型:为什么还是 PHP 后端

这个项目后端最终选了 PHP,而不是 Java 或者 Node。这不是拍脑袋决定的,主要从几个维度考虑。

首先是开发周期。活动型商城从立项到上线通常只有几周时间,甲方催得紧,而且业务逻辑相对标准,PHP 生态里的成熟框架(项目用的 ThinkPHP 8,用 Laravel 也完全没问题)能提供大量现成能力,路由、ORM、中间件、验证器都是开箱即用,不用从零搭地基。

其次是部署和运维成本。这种规模的项目通常就是一台云服务器,PHP 的部署简单直接,Nginx + PHP-FPM + MySQL + Redis 就是完整架构,出了问题排查也方便。选 Java 的话,虽然性能上限更高,但部署链路、构建流程、服务器资源要求明显更重,对这类体量来说是杀鸡用牛刀。

还要考虑后续维护。这类系统的后续维护往往不是原班人马,PHP 作为使用面极广的语言,无论是甲方自建团队还是找外部服务商,接手门槛都比一些小众技术栈低得多。

数据层用的 MySQL,理由是电商核心场景绕不开事务。订单创建、库存扣减、销量累加必须放在同一个数据库事务里执行,保证任何一步失败都可以整体回滚。缓存用 Redis,主要承担首页内容缓存、活动状态缓存、并发尖峰下的库存预扣和队列任务。一台 2 核 4G 的服务器,支撑这种规模的活动商城绰绰有余。

1.3 双端策略:小程序和 APP 共用一套后端的思路

甲方最初提的需求是“小程序 + APP”双端。这里要提醒大家一句话:不要让“多端”绑架了架构。无论是小程序还是 APP,本质上都是后端的客户端,后端只做一套 RESTful API,返回 JSON 就足够了。

小程序是主入口,承担日常交易。用户从活动宣传页、公众号文章、现场扫码进入小程序,浏览、下单、支付、查订单全部在这里完成。这也是微信生态里最自然的转化路径。

APP 端的定位要务实。对于一场活动来说,让用户专门下载一个 APP 的意愿很低。但甲方往往希望有自己的 APP 作为长期品牌承载。最稳妥的方案是用 uni-app 把同一套前端代码编译成 iOS 和 Android 应用,这样开发成本可控,后续更新也方便。如果前端已经用原生小程序写了,也不再想重写,另一个可操作方案是 APP 内嵌 WebView 直接加载 H5 版商城,先把需求交付掉,等运营确认长期有人用再考虑做原生壳也不迟。

登录态是双端必须统一的点。小程序端走微信登录,前端wx.login拿 code 换 openid,后端签发自己的 token。APP 端没有微信 code,用手机号 + 短信验证码登录。后端生成统一的 token,两端的请求都带上Authorization头,后续逻辑完全一致。

2. 数据库设计与核心业务模型

2.1 文创商品模型:SKU、规格与库存怎么建模

文创产品的商品模型和普通电商一样,需要拆两层:商品(SPU)和规格(SKU)。哪怕有的商品只有一种规格,也建议保留 SKU 表,因为后面库存、价格、销量都要挂在 SKU 级别。

商品主表大概长这样:

CREATE TABLE `goods` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `activity_id` int unsigned NOT NULL DEFAULT '0' COMMENT '所属活动ID', `category_id` int unsigned NOT NULL DEFAULT '0' COMMENT '分类ID', `title` varchar(200) NOT NULL COMMENT '商品标题', `subtitle` varchar(255) DEFAULT '' COMMENT '副标题', `cover` varchar(255) NOT NULL COMMENT '封面图', `images` text COMMENT '轮播图,JSON数组', `detail` longtext COMMENT '详情富文本', `status` tinyint NOT NULL DEFAULT '1' COMMENT '1上架 0下架', `sort` int NOT NULL DEFAULT '0', `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

SKU 表:

CREATE TABLE `goods_sku` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `goods_id` int unsigned NOT NULL, `sku_name` varchar(100) NOT NULL COMMENT '规格名,如:铜质 / 精装版', `price` int unsigned NOT NULL COMMENT '价格,单位分', `stock` int NOT NULL DEFAULT '0' COMMENT '库存', `sales` int NOT NULL DEFAULT '0' COMMENT '销量', `image` varchar(255) DEFAULT '' COMMENT '规格图', `status` tinyint NOT NULL DEFAULT '1', PRIMARY KEY (`id`), KEY `idx_goods` (`goods_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

这里有几个容易踩的细节。

价格字段必须用整数分存储。PHP 的浮点数做加减乘除会出现精度问题,比如19.9 + 0.1并不严格等于20.0。所有金额在写入数据库前统一转成分为单位,展示的时候再除以 100,前后端约定好规则,能省掉大量对账时莫名其妙的“差一分钱”。

库存方面,文创产品往往有强烈的“限量”属性,库存数量不大但绝对不允许超卖。后面会讲并发控制的具体做法。

商品和活动的关系是:商品挂在活动下,一个活动有多件商品。接口层面控制“只能看到进行中活动下的上架商品”,避免活动结束用户仍能下单。

2.2 订单状态机与支付流程

订单表建议拆成订单主表和订单商品明细表。明细表必须冗余一份商品标题、规格名、单价、数量,不能下单后去实时联表查商品表。因为商品可能改价、改名、甚至删除,历史订单要保留下单那一刻的“快照”。

CREATE TABLE `orders` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `order_no` varchar(32) NOT NULL COMMENT '订单号', `user_id` int unsigned NOT NULL, `activity_id` int unsigned NOT NULL DEFAULT '0', `total_amount` int NOT NULL COMMENT '总金额(分)', `status` tinyint NOT NULL DEFAULT '0' COMMENT '0待支付 1已支付 2已发货 3已完成 4已关闭 5退款中 6已退款', `pay_time` datetime DEFAULT NULL, `consignee` varchar(50) DEFAULT '' COMMENT '收货人', `address` varchar(255) DEFAULT '' COMMENT '收货地址', `remark` varchar(255) DEFAULT '' COMMENT '备注', `created_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_no` (`order_no`), KEY `idx_user` (`user_id`, `status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

订单状态流转是整个系统最核心的部分。正常路径:待支付 → 已支付 → 已发货 → 已完成。异常路径:超时未支付自动关闭、支付后用户申请退款。

支付流程要注意一个顺序问题:什么时候扣库存。正确做法是在用户提交订单时,事务内同时完成“插入订单 + 扣减库存”,而不是等支付回调回来再扣。原因是支付回调是异步的,如果等回调才扣库存,可能出现用户支付成功了但库存已经被别人抢走的情况。当然,先扣库存也有代价,会有用户下单不支付的“占库存”问题,所以必须配套超时关单机制:订单创建后 30 分钟未支付,自动把订单状态置为已关闭,同时把库存回补回去。实现上可以用一个每分钟执行一次的定时脚本,扫描超时订单处理;更优雅的方案是用 Redis 延迟队列,但小体量项目用脚本扫描完全够用。

2.3 活动专题与内容展示的关联设计

文创商城不是冷冰冰的商品货架,用户需要先被内容打动,才会去下单。所以活动专题和内容展示是系统里很重要的一环。

活动表、文章资讯表、轮播图表可以这样设计:

  • 活动表记录活动标题、副标题、开始时间、结束时间、banner 图、状态。
  • 文章表用来承载活动资讯、文物背后的故事、创作者访谈这类内容。
  • 轮播图挂在活动下,首页展示当前进行中的活动。

首页接口的返回结构大致是:活动信息 + 轮播图列表 + 推荐商品列表。为了减少数据库压力,这个聚合接口的结果可以整体缓存到 Redis,活动管理后台有任何变更时清除缓存,让用户下次请求重新组装。

这类内容型电商有一个设计细节:商品详情页里不要只放规格参数,要把“故事内容”也放进去。商品富文本详情可以加入图文混排,比如纪念徽章的设计草图、文物元素的出处说明。这在红色文物活动场景里尤其重要,用户买的不仅是一件商品,更是一份文化纪念。内容到位了,转化率自然能上去。

3. 功能实现:从后端到前端的完整链路

3.1 后端接口设计与扣库存逻辑

后端接口按业务模块划分,统一响应格式{ code: 0, message: 'ok', data: {} },code为 0 表示成功,非 0 表示业务异常。这种约定虽然老套,但前端处理起来非常统一,不需要为不同接口写多套判断逻辑。

核心接口清单大致如下:

模块接口方法说明
内容/api/homeGET首页聚合数据(活动、轮播、推荐商品)
商品/api/goods/listGET商品列表,支持分类、活动过滤
商品/api/goods/detailGET商品详情 + SKU 列表
订单/api/order/createPOST创建订单
支付/api/pay/wechatPOST微信支付下单,返回支付参数
订单/api/order/listGET我的订单列表
订单/api/order/detailGET订单详情
核销/api/order/verifyPOST现场提货码核销(管理员)

创建订单这个接口是重点,贴一段核心逻辑框架:

public function createOrder(Request $request) { $userId = $request->userId; $skuId = (int) $request->input('sku_id'); $count = (int) $request->input('count', 1); if ($count <= 0 || $count > 99) { return fail('数量不合法'); } Db::startTrans(); try { // 查询SKU并加行锁,防止并发下超卖 $sku = Db::name('goods_sku') ->where('id', $skuId) ->lock(true) ->find(); if (!$sku || $sku['status'] != 1) { throw new \Exception('商品已下架'); } if ($sku['stock'] < $count) { throw new \Exception('库存不足'); } // 扣减库存 Db::name('goods_sku') ->where('id', $skuId) ->dec('stock', $count) ->inc('sales', $count) ->update(); // 生成订单号、插入订单和明细…… Db::commit(); return success(['order_id' => $orderId]); } catch (\Exception $e) { Db::rollback(); return fail($e->getMessage()); } }

这里用lock(true)对 SKU 行加锁,保证同一时间只有一个请求能读到最新的库存值。用户量不大的场景下完全够了。如果以后要做“整点限量开抢”这种高并发场景,再把 Redis 原子扣减方案加上,这个后面会细说。

订单号生成有个经验:不要用date() + 随机数简单拼接,并发下重复概率不低。建议用时间戳 + 用户ID后四位 + 4位随机数,并且数据库订单号字段加唯一索引,插入失败重新生成,保证万无一失。

3.2 小程序端实现要点

小程序端用的是原生微信小程序开发,页面结构不算复杂:首页、商品列表、商品详情、确认订单、订单列表、个人中心,一共六个核心页面。

登录逻辑是小程序端最需要注意的点。流程是:wx.login()获取临时 code → 后端调用微信接口换取 openid → 后端查找或创建用户 → 签发自定义 token 返回前端。前端把 token 存入 storage,后续所有请求在 header 里带上。这个方案比前端直接拿 openid 去对后端更安全,openid 不暴露给前端调用链路。

支付对接的流程也是固定套路:

  1. 用户确认订单,前端把 sku_id 和数量传给后端。
  2. 后端创建本地订单,然后调用微信支付接口(需要拿到用户的 openid、订单金额、回调地址)获取预支付交易会话标识prepay_id。
  3. 后端二次签名后返回给前端wx.requestPayment所需的 timeStamp、nonceStr、package、signType、paySign 参数。
  4. 前端调用wx.requestPayment拉起微信支付面板。
  5. 支付成功后前端通过wx.showToast给用户反馈,但订单状态的最终确认必须以后端收到的异步回调为准。

这里有一个必须提醒的坑:不要在前端拿到支付成功回调就立刻把本地订单状态改成“已支付”。小程序端wx.requestPayment的 success 只代表“用户完成了支付动作”,后端回调链路上可能还有延迟。如果用户支付成功后立即关闭页面,而后端回调因为网络问题晚了几秒,用户重新打开订单列表看到的可能还是“待支付”。这种体验很糟,但更糟的是误判。订单状态永远以服务端为准。

小程序端商品列表页建议做按下拉刷新和上拉加载更多,分页用page和page_size,后端统一限制最大返回条数。列表页请求时带上活动 ID,避免用户看到其他时段的活动商品。

3.3 APP 端的轻量化实现与打包发布

APP 端如果用 uni-app 编译,前端代码可以直接复用大部分小程序逻辑。但有几个适配点必须处理:

  • 登录方式:小程序用微信 code,APP 端改用手机号验证码。后端需要新增发送短信验证码接口和验证码校验接口,短信服务可以用云厂商的短信 API,签名和模板需要提前申请。
  • 支付方式:小程序走微信小程序支付,APP 端要接入微信 App 支付,需要单独在微信开放平台注册移动应用,拿到 App 的 appid,并且配置包名和签名。如果不想折腾微信支付,也可以接入支付宝 App 支付,但用户习惯上通常更倾向微信。
  • 上架材料:应用商店上架需要软件著作权证书、隐私政策、用户协议等材料。隐私政策在项目启动时就要准备,里面必须如实说明收集了哪些用户信息、用途是什么。

如果只是“先有 APP 再说”,我个人的建议是用 WebView 壳方案。后端把商城页面输出成适配移动端浏览器的 H5,APP 端用原生 WebView 加载,登录直接用 H5 页面内的手机号验证码登录。这样做开发量最小、迭代最快,但缺点也很明显:无法调用 APP 原生能力,加载速度略慢,体验稍差。怎么选,完全取决于甲方对 APP 的预期定位。

4. 上线前后避坑清单

4.1 支付回调与对账的正确姿势

微信支付异步回调是整个项目中最容易出问题的环节。回调地址必须是公网可访问的 HTTPS 地址,回调收到后第一步不是改订单状态,而是做三件事:

  1. 验证签名,确认请求确实来自微信服务器。
  2. 校验订单号,确认这个订单在本地存在。
  3. 校验金额,确认回调金额和订单金额一致。

全部通过后,还要做一个“业务幂等”处理:如果订单已经是已支付状态,直接返回成功,不再重复执行更新。否则回调重复通知时,可能出现库存扣两次、销量加两次的问题。这类问题通常在压测或用户连续支付时暴露,提前做好能省很多心。

对账建议从上线第一天就开始做。每天写一个脚本,调用微信商户平台的账单接口,把前一天的支付记录和本地订单表比对一遍,检查有没有“本地已生成订单但没收到回调”的情况。这个动作不难,但关键时刻能救命。活动结束要结算时,账面差一分钱都对不上,那时候再手工翻日志就痛苦了。

关于退款,如果活动结束需要批量下架未支付订单,或者用户申请退款,后端要留一套完整的退款流程。微信支付的退款接口也需要证书和商户 API 密钥,建议把退款做成后台手动操作,不要做自动触发,避免误退。

4.2 小程序审核与合规自查

小程序涉及线上支付,类目一般选择“商家自营”,不同商品类目可能要求不同资质。这个项目卖的是文化用品、工艺纪念品,普通资质基本够用。但如果文创商品涉及图书,部分平台会要求出版物经营许可;涉及食品、茶饮类联名商品,要求就更严。所以,选品阶段就要和甲方确认商品类目,提前准备证照,不要等开发完了才发现提交审核被卡住。

内容审核是这类主题项目的另一个重点。活动页面和商品文案必须严格规范,不夸大宣传,不使用不规范的网络用语,不涉及对历史事件、人物的不当描述。这是底线问题,宁可文案写得平实一点,也不能为了传播效果触碰红线。小程序审核人员对涉及文化、纪念属性的内容审核通常更仔细,措辞尤其要注意。

另外,小程序里如果出现“虚拟支付”行为,比如购买线上讲解音频、虚拟徽章这类,微信是不允许用微信支付收款的。本项目卖的是实体文创产品,没有这个问题。但有些甲方会想着把线上展览门票、电子讲解券也放进商城,一旦出现这种需求,就要单独设计会员积分、兑换等方案,而不是直接走微信支付。

小程序提交审核前,务必准备一个测试账号和一套完整的测试商品数据。审核人员在审核时会被要求走通整个购物流程,如果订单提交时提示“库存不足”或者页面空白,会直接驳回。常见驳回原因还包括:未登录状态下浏览受限、用户协议缺失、隐私政策没有弹窗提示等,上线前逐项检查一遍。

4.3 并发开抢与库存超卖问题

活动型商城的一个典型场景是开售当天瞬时流量集中。假设活动商品只有 500 件,开售前 10 分钟大量用户涌进来抢购,如果还是简单用数据库行锁,数据库压力会非常大,可能出现死锁、超时。这种情况下建议换一套方案:

  1. 预扣库存:活动开售前把商品总库存量加载到 Redis,用一个 key 记录当前剩余量。
  2. 用户下单时,先执行 Redis 原子自减操作,比如DECR stock_key,如果返回的值小于 0,说明库存已经扣完,直接返回“已抢光”。
  3. Redis 预扣成功后,再走数据库下单流程。数据库里仍然保留一个总库存字段,但真正的门槛判断以 Redis 为准。
  4. 用户 30 分钟未支付,定时任务关闭订单,同时把 Redis 库存回补,数据库库存也要做一致性更新。

这套方案的好处是 Redis 的原子操作性能极高,单机 Redis 每秒几万次操作没压力,能把数据库从高并发冲击中解放出来。坏处是多了一层 Redis 和数据库状态的一致性保障工作,活动结束后要写一个库存核对脚本,把 Redis 剩余量和数据库商品 SKU 的剩余量做一次比对校准。

对于体量更小的内部活动,直接使用数据库行锁 + 事务方案就足够了,不需要上 Redis。判断标准很简单:预估同时抢购的人数是否超过 200 人。200 以下,数据库扛得住;超过 500,就要认真考虑 Redis 预扣了。

4.4 常见问题排查速查表

把项目上线后最容易遇到的问题整理成一张表格,遇到同样的毛病可以直接对照排查:

现象可能原因处理方法
支付成功但订单仍是待支付回调地址错误、回调验签失败、回调业务处理异常开启回调日志,检查回调域名和签名,确认订单金额比对逻辑
用户重复点击下单生成了多个订单前端未做提交防抖、后端缺少幂等控制前端按钮加 loading 状态,后端对同一用户同一 SKU 短期内重复下单做限制
商品显示有库存但下单提示库存不足Redis 预扣库存与数据库库存不一致核对 Redis key 与数据库 SKU 库存值,运行对账脚本校准
小程序支付后自动返回但订单未更新前端在wx.requestPaymentsuccess 里提前改了状态前端只提示支付成功,订单状态以服务端最终数据为准
APP 端支付拉起不了包名签名与微信开放平台配置不一致、未设置 universal link核对包名和签名的 MD5 值,检查 iOS 关联域名配置
小程序审核被驳回类目不符、隐私政策缺失、测试流程走不通查看驳回原因,补充资质和协议,给出可用的测试账号
活动结束商品还能进入购物车接口没有校验活动状态商品列表和详情接口都校验活动起止时间,过期直接返回下架状态

这里再补充一个容易被忽视的点:所有后端接口的异常日志,日志格式里务必包含请求路由、请求参数、用户 ID、完整堆栈和请求耗时。排查线上问题的时候,没有日志就像瞎子摸象。建议从项目第一天就把日志中间件写好,后面会省下大量时间。

5. 写在最后:项目做完后的一点经验

开发这类活动型商城,最大的技术难点并不在某个单独的功能,而是所有业务要在“活动”这个时间维度上保持自洽。商品跟着活动上架,活动结束全部下架;订单在活动期间产生,售后在活动结束后还要持续处理;库存有严格的限量,过了这场活动可能永远不再补货。每一步设计都要把“这场活动结束以后怎么办”想清楚,这一点是这类项目和其他普通商城的本质区别。

从实操角度说,我的建议是开工前先在纸上把“用户下单 → 支付 → 发货/核销 → 完成”这条链路完整画出来,尤其是每个节点的异常分支(超时、退款、库存不足)都标出来,再让后端开发去建表写接口。很多项目工期延误,不是因为技术难,而是因为业务流程图没画清楚,开发过程中频繁改需求。

这类商城后续最有价值的扩展方向其实是数据统计。活动一场接一场,把每场活动的商品浏览量、下单转化率、售罄率、客单价、退款率沉淀下来,下一场活动的选品、定价、备货数量就都有据可依了。这比在界面上堆更多花哨功能有意义得多。如果甲方在活动结束后还愿意继续运营,还可以把老用户的复购数据利用起来,做一些定向推送和会员运营,让活动带货的短期流量沉淀成长期品牌资产。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 8:17:26

AI问诊网站设计方案:从定位、流程到技术落地的完整拆解

晚上十一点&#xff0c;家里老人突然发热咳嗽&#xff0c;要不要直接冲急诊&#xff1f;很多人都有过这种纠结。AI问诊网站设计方案&#xff0c;本质上就是给这种纠结提供一条结构化路径——用户用自然语言描述症状&#xff0c;系统通过多轮对话收集关键信息&#xff0c;输出分…

作者头像 李华
网站建设 2026/10/18 8:17:09

QColor 深度解析:从底层机制到实战避坑指南

实际开发 Qt 项目时&#xff0c;颜色处理几乎躲不开。无论是 QSS 样式表、自绘控件、数据可视化图表&#xff0c;还是简单的按钮状态切换&#xff0c;QColor 都会以一个高频工具类的身份出现在代码里。但这个类并不是大家想象中那么“一眼望穿”&#xff0c;很多细节、坑点和性…

作者头像 李华
网站建设 2026/10/18 8:16:52

Day20复盘:20天用Python+Pillow打造图片批量处理工具

看到“day20”这个标题&#xff0c;你可能觉得奇怪&#xff1a;不就一个天数吗&#xff1f;但如果你做过任何以“连续记录”为驱动的个人项目&#xff0c;就会懂第20天是个非常微妙的节点——新鲜感已经耗得差不多&#xff0c;离终点又还有一截&#xff0c;要么靠惯性滑过去&am…

作者头像 李华
网站建设 2026/10/18 8:16:46

10/0.4kV配电工程电气设计要点详解:从负荷计算到运行复盘

做了不少10/0.4kV配电工程电气设计之后&#xff0c;我最大的感受是&#xff1a;这类项目看着入门门槛不高&#xff0c;电路似乎就是“进线—变压器—出线”三段&#xff0c;但真正能把图纸一次审过、送电后不出毛病的&#xff0c;拼的全是细节。变压器容量选大了&#xff0c;几…

作者头像 李华
网站建设 2026/10/18 8:15:42

基于YOLOv8/YOLO11的混凝土裂缝检测系统实战与OpenCV部署

混凝土表面的裂缝和坑洞&#xff0c;看着不起眼&#xff0c;但对结构安全来说&#xff0c;每一道裂缝都可能是内部损伤的警报信号。这个项目涉及用YOLOv8和YOLO11分别训练混凝土裂缝检测数据集&#xff0c;并构建一套基于深度学习的混凝土缺陷检测系统。我把自己从数据打标、模…

作者头像 李华
网站建设 2026/10/18 8:15:42

直接赋值、浅拷贝与深拷贝:内存共享、隔离与工程选型

写这篇文章的起因有点丢人——某次项目评审会上&#xff0c;我被当场问了一句"你这段代码为什么不用深拷贝"&#xff0c;我愣了一下&#xff0c;然后发现自己在用一堆零散经验解释一个本来应该很基础的概念。回头把"直接赋值、浅拷贝、深拷贝"这一组操作彻…

作者头像 李华