简介:这份ASP编写的殡葬网源码是一套面向殡葬服务机构和相关开发者的完整网站平台程序,核心亮点在于集成网上公墓功能,支持在线创建纪念页面、发布逝者信息与开展悼念活动,同时涵盖殡葬服务展示、用品商城、预约服务等常用模块,适合需要搭建数字化祭祀平台的个人或企业使用。资源压缩包共含2000个文件,大小约161.4MB,以ASP动态页面文件为核心,辅以大量GIF、JPG、PNG图片素材用于界面展示,CSS与JS文件负责前端样式和交互,另含DB、MDB数据库文件及BAK备份文件,基本具备直接部署运行的条件。包内还收录了SWF动画、MP3音频及HTML静态页面等多媒体素材。目前已有63人浏览学习,对正在入门ASP开发或希望快速搭建殡葬类网站的技术人员具有一定参考价值。通过研究源码结构、后台管理模块与数据库设计,读者可以了解此类行业网站的功能规划思路,掌握公墓纪念页面的实现方法,并借鉴其界面布局和交互设计经验。
1. 殡葬网源码带网上公墓,先分清它是企业官网还是业务系统
客户说想要一个带网上公墓的殡葬网站时,大多数开发者以为是在改企业官网。等源码包到手、本地跑通才发现,网上公墓不是一个页面,而是纪念堂、祭拜、留言、代祭下单、内容审核、支付回单这一整条业务链路。这类殡葬网源码通常以源码建站形式交付,前台展示园区介绍与殡葬服务,后台挂一套可独立部署的网上公墓程序;它真正解决的是线下陵园把祭扫服务搬到线上、代祭服务形成订单闭环的问题。适合接殡葬信息化外包项目的开发者、帮本地陵园做方案演示的技术人员,以及想做云祭祀产品的早期团队。这个判断直接影响后面的技术选型与数据库设计,下面的每一步都围绕这条主线展开。
2. 网上公墓不是一个页面:拆出五个必须存在的业务模块
把“网上公墓”四个字拆开看,它至少包含五块:纪念堂、祭拜行为、留言互动、代祭服务、线下二维码绑定。缺了代祭,它只是一个内容展示站;缺了二维码绑定,线下墓园和线上系统永远连不起来。很多源码包不会直接叫“网上公墓”,菜单里可能是“云祭祀”“网上灵堂”“纪念堂管理”,但底层逻辑基本一致。
2.1 纪念堂:从一张背景图到一张主表的建模思路
纪念堂是整个网上公墓的根记录,不是页面。源码数据库里通常有一张类似memorial_hall的表,记录创建人、逝者姓名、出生与去世日期、主题模板、封面图、二维码地址、审核状态。先想清楚一点:纪念堂页面本身是模板渲染出来的,用户建堂时只能选模板、填资料,不能改HTML。否则运营阶段会出现大量千奇百怪的页面样式,维护成本直接失控。
墓碑二维码绑定是很多开发者容易忽略的细节。线下墓碑上的二维码不能直接写死纪念堂ID,因为碑刻好就不能改。常见做法是生成一个关联码,用户扫码后进入系统,管理员在后台把二维码与具体穴位、纪念堂绑定。
// 扫码进来:先查二维码是否已绑定 $sql = "SELECT * FROM memorial_hall WHERE qrcode = :qrcode LIMIT 1"; $stmt = $pdo->prepare($sql); $stmt->execute([':qrcode' => $qrcode]); $hall = $stmt->fetch(); // 没绑定或已解绑直接拒绝,避免二维码被复制后乱跳 if (!$hall || $hall['bind_status'] != 1) { exit(json_encode(['code' => 1, 'msg' => '二维码未激活,请联系管理员'])); } // 跳转到纪念堂前台页面,使用伪静态地址便于收录 header('Location: /hall/' . $hall['id'] . '.html');这里的bind_status字段取值建议用 0、1、2 分别表示未绑定、已绑定、已解绑。qrcode字段存的是二维码的唯一标识串,不是完整URL。这样换域名时只需要在系统里批量拼接新地址,不需要重新刻碑。$pdo是已经建立好的数据库连接,生产环境不要用字符串拼接SQL,防止注入。
2.2 祭拜引擎:从“上香”按钮到一份可对账的祭拜记录
点击上香、献花、点烛、写留言,技术链路分两部分:记录写入、页面展示。很多老源码把这两件事揉进同一个请求里,结果清明前后同一纪念堂被几十个请求同时命中,页面直接白屏。常见做法是写入走异步接口,展示走静态化缓存。
前端提交部分大概是这样的:
// 点击“上香”按钮后触发 fetch('/api/memorial/rite', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ hall_id: 182, rite_type: 'incense', quantity: 3 }) });后端收到后只做校验和落库,不返回整页HTML:
$data = [ 'hall_id' => intval($_POST['hall_id']), 'rite_type' => trim($_POST['rite_type']), 'quantity' => max(1, intval($_POST['quantity'])), 'create_time' => time(), ]; // 祭品类型必须走白名单,不能用用户输入直接入库 if (!in_array($data['rite_type'], ['incense', 'flower', 'candle', 'paper'], true)) { exit(json_encode(['code' => 1, 'msg' => '不支持的祭拜类型'])); } $id = $pdo->insert('memorial_rite', $data); // 更新纪念堂当天的统计字段,不阻塞主流程 $pdo->update('memorial_hall', ['today_rite_count' => 'today_rite_count+1'], ['id' => $data['hall_id']]); exit(json_encode(['code' => 0, 'id' => $id]));rite_type必须由后端配置表决定,不能在前端随便传一个字符串进来,否则会出现“赛博纸钱”这种不在预期内的品类。quantity限制在 1 到 9,防刷量,也防恶意传大数字打爆统计字段。规模不大时同步写库没问题;如果预期量很大,把祭拜记录投递到 Redis 队列,定时批量落库,页面只读聚合统计表。
2.3 代祭服务:真正把流量变成钱的模块,也是多数源码包藏得最深的模块
普通留言是一行记录,代祭是一笔订单,两者差别巨大。检查源码时先搜“代祭”“代客祭扫”“服务订单”关键词,没有这个模块,这套程序就只能算半个业务系统。
代祭的完整链路是:用户选祭品包 → 提交订单 → 支付 → 后台派单 → 执行人到现场 → 拍照或短视频回传 → 用户在前台订单详情看到回传内容。任何一个环节断裂,比如照片回传没做,运营就只能靠电话安抚客户。
订单状态在代码里一般这样定义:
define('ORDER_WAIT_PAY', 0); // 待支付 define('ORDER_PAYED', 1); // 已支付,待派单 define('ORDER_EXECUTING', 2); // 执行中 define('ORDER_FINISHED', 3); // 已完成 define('ORDER_CANCELED', 4); // 已取消 define('ORDER_REFUNDING', 5); // 退款中 define('ORDER_REFUNDED', 6); // 已退款状态转换必须限制:待支付只能到已支付或已取消;已支付只能到执行中或已取消;执行中只能到已完成;已完成不能回退。并发场景下要从数据库层面兜底,不能让两个请求把订单状态“穿越”了:
UPDATE sacrifice_order SET service_status = 2, executor_id = 8, executed_at = UNIX_TIMESTAMP() WHERE id = 22 AND service_status = 1;受影响行数为 0 时,说明订单状态已经被别人改过,前端应提示“订单状态已变更,请刷新页面”。这种做法比先 SELECT 再 UPDATE 更省事,也更安全。
2.4 全局状态机:五个状态位,一条都不能少
业务耦合越深,状态位越要拆得细。网上公墓里至少有五组独立状态:
| 状态位 | 常见取值 | 作用 |
|---|---|---|
| 内容审核状态 | 草稿、待审、已发布、已下架 | 控制纪念堂和留言是否对外可见 |
| 支付状态 | 未支付、已支付、已退款 | 只描述资金流 |
| 订单服务状态 | 待支付、已支付、执行中、已完成、已取消、退款中、已退款 | 描述服务履约过程 |
| 二维码绑定状态 | 未绑定、已绑定、已解绑 | 控制线下到线上的入口 |
| 展示状态 | 展示中、隐藏 | 运营手动控制前台可见性 |
支付状态和订单服务状态必须分开。一个订单完全可能存在“已支付但服务未执行”的情况,如果合成一个字段,运营后台就没法准确筛出待派单量。这也是后面做数据报表时最容易混乱的地方。
3. 本地把整套程序跑起来:环境组合与最小启动命令
拿到源码的第一件事不是看功能,而是识别技术栈。目前的殡葬网源码分两大类:一类是 PHP 系,入口在public或根目录index.php,配 MySQL、Redis;另一类是近年出现的企业版,基于 Spring Boot,结构上是src/main/java加application.yml。后者一般带后台管理端,部署稍重。下面的步骤以 PHP 源码包为例,这套流程覆盖了市面上大多数快速建站类程序。
3.1 先分清源码包里的技术栈和环境要求
解压后先看根目录。PHP 系常见结构是:application放业务代码,runtime放缓存日志,public是 Web 入口,根目录有composer.json。如果看到pom.xml或package.json加src/main/java,那就是 Java 系,部署要装 JDK 和 Maven。
本地环境推荐用 PHP 集成环境,省去手动编译。建议 PHP 7.4 或 8.0,MySQL 5.7 或 8.0,Nginx 1.22 以上,Redis 6.x。尽量不要用 PHP 5.6,老版本对密码哈希和时区的支持太差,现有源码未必兼容。
3.2 本地启动的最小操作序列:以 PHP 源码包为例
步骤按顺序来,每步都有依赖关系:
# 1. 解压源码到站点根目录 unzip 殡葬网源码.zip -d /www/cemetery # 2. 创建数据库并导入初始数据,注意字符集必须是 utf8mb4 mysql -uroot -p --default-character-set=utf8mb4 \ -e "CREATE DATABASE cemetery DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" mysql -uroot -p cemetery < sql/cemetery_init.sql # 3. 修改数据库连接配置 vim application/database.php # 对应字段改成: # 'hostname' => '127.0.0.1' # 'database' => 'cemetery' # 'username' => 'root' # 'password' => '你自己的密码' # 4. 给缓存目录写权限 chmod -R 755 runtime chown -R www:www runtime字符集用 utf8mb4 而不是 utf8,是因为逝者姓名和留言里可能出现生僻字、特殊符号,传统 utf8 在 MySQL 里最多存 3 字节,部分汉字会直接报错或变成乱码。导入 SQL 时也必须带--default-character-set=utf8mb4,否则表结构注释里的中文会乱。
3.3 伪静态、后台登录入口与默认口令
这套程序的前台地址如果是/index.php?s=/hall/12.html这种格式,最好配伪静态。Nginx 下常见配置是:
location / { if (!-e $request_filename) { rewrite ^/(.*)$ /index.php?s=$1 last; } }Apache 环境一般是在站点根目录放.htaccess,内容逻辑相同。配好后访问/hall/12.html才不报 404。如果伪静态没生效,先在配置里确认location没有被其他规则抢占,很多本地翻车都是 rewrite 规则顺序问题,这不是玄学,是 Nginx 配置文件从上到下匹配的必然结果。
后台入口通常在/index.php/admin或/admin.php。初始化口令基本都是admin/admin、admin/123456这种组合,上线前必须改:
-- 老系统的密码常见是 md5 加盐,不要只改 password 字段 UPDATE admin_user SET password = MD5(CONCAT('你的新密码', salt)), update_time = UNIX_TIMESTAMP() WHERE id = 1;salt字段如果单独存在,就必须把它一起取出来参与计算,否则改完密码之后怎么登都提示账号密码错误。部分老源码的 salt 写死在配置文件里,情形不同,处理方式一样:以初始密码规则为准,不要用 MD5('新密码') 一刀切。
3.4 上线前必须检查的配置文件清单
本地跑通不代表能直接上公网。我一般在上线前按下面这张表逐项过一遍:
| 检查项 | 要求 | 备注 |
|---|---|---|
| runtime 目录 | 可写 | 不可写时页面会白屏但无报错日志 |
| PHP 扩展 | openssl、curl、fileinfo、pdo_mysql | 支付回调、上传图片都依赖这几项 |
| debug 模式 | 关闭 | 开启时错误日志会直接暴露数据库密码 |
| Redis 配置 | 地址、密码、库编号正确 | 祭拜队列和缓存都依赖它 |
| 初始 SQL 备份 | 单独归档 | 重置演示环境时要用 |
| 后台默认账号 | 已修改且强口令 | 爆破脚本最喜欢扫默认路径加默认密码 |
调试模式关闭后,如果页面再出问题,日志会落到 runtime 目录下,不会打到前端。这一步不做,上线当天爆出的数据库账号密码比你想象的快。
4. 网上公墓的库表设计:四张核心表,每条字段都要有用处
这套系统能不能扛住清明那波流量,关键不在服务器配置,而在表怎么建。网上公墓的库表骨架一般是四张:家属用户表、纪念堂表、祭拜记录表、代祭订单表。字段设计不合理,后面每一轮加功能都像补丁叠补丁。
4.1 家属用户与纪念堂:两张表把“人”和“堂”的关系定死
用户表不要只存手机号,还要存relation_type,区分游客、家属、管理员代建。游客可以看,家属才能建堂和管理。很多源码里缺这个字段,结果游客也能建堂,运营后台只能人工删。
CREATE TABLE `memorial_user` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `openid` varchar(64) NOT NULL DEFAULT '', `mobile` varchar(20) NOT NULL DEFAULT '', `nickname` varchar(50) NOT NULL DEFAULT '', `relation_type` tinyint NOT NULL DEFAULT 0 COMMENT '0游客 1家属 2管理员代建', `create_time` int unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `uk_openid` (`openid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家属用户表';openid是微信生态里的唯一标识,做唯一索引是必须的。如果程序要同时跑微信公众号和小程序,unionid也建议预留,但不要一开始就把所有可能字段都堆上。
纪念堂表要与用户表建立明确的归属关系:
CREATE TABLE `memorial_hall` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `member_id` int unsigned NOT NULL COMMENT '创建人ID', `deceased_name` varchar(30) NOT NULL COMMENT '逝者姓名', `birth_date` date DEFAULT NULL, `death_date` date DEFAULT NULL, `hall_theme` varchar(30) NOT NULL DEFAULT 'default', `cover_img` varchar(200) NOT NULL DEFAULT '', `qrcode_url` varchar(200) NOT NULL DEFAULT '' COMMENT '二维码标识', `bind_status` tinyint NOT NULL DEFAULT 0 COMMENT '0未绑定 1已绑定 2已解绑', `audit_status` tinyint NOT NULL DEFAULT 0 COMMENT '0草稿 1待审 2已发布 3已下架', `create_time` int unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `idx_member_time` (`member_id`, `create_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='纪念堂表';出生和去世日期用date类型而不是时间戳,是为了避免时区换算带来的日期偏移。hall_theme是模板标识,不存整段 HTML。bind_status独立成字段,是因为线下墓碑注册和线上建堂经常是先后发生的,需要有个中间状态让管理员去校验。
4.2 祭拜记录与留言:单表查询会拖垮页面
祭拜记录是这套系统里写入量最大的表。每条上香、献花、留言都是一行记录。老源码容易犯的错是把所有类型混在一张表,用type字段区分,结果热门纪念堂一天几万条写入,前端翻页越来越慢。
正确的姿势是拆表或分表存储。至少保证祭拜记录表的联合索引能覆盖前台最常见的查询路径:
ALTER TABLE `memorial_rite` ADD KEY `idx_hall_status_time` (`hall_id`, `audit_status`, `create_time`);audit_status参与索引,是因为前台只展示审核通过的内容,运营后台要查待审核内容;create_time参与索引,是因为纪念堂页面默认按时间倒序展示最近祭拜。查询时如果发现Extra列出现Using filesort,说明还是没走对索引。
再往后,热数据与冷数据要分离。我一般建议最近 6 个月的祭拜记录留在主表,更早的归档到历史表或按月分表。前台统计“累计祭拜次数”时,直接读纪念堂表里的汇总字段,避免每次 COUNT 全表。这个汇总字段可以在写入时异步叠加,也可以在定时任务里重算。
4.3 祭品配置与代祭订单:价格、软删除与状态原子性
祭品表很简单但经常被做坏。核心字段就四个:名称、价格、图片、是否在线。要注意的是“下架祭品仍可下单”的老毛病,所以前台取祭品列表必须带is_online = 1条件,下单接口还要再校验一次。
CREATE TABLE `sacrifice_pack` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `price` decimal(10,2) NOT NULL DEFAULT '0.00', `img_url` varchar(200) NOT NULL DEFAULT '', `is_online` tinyint NOT NULL DEFAULT 1 COMMENT '0下架 1上架', `sort_order` int NOT NULL DEFAULT 0, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='代祭祭品包';代祭订单表是资金流和履约流的交点,除了常规字段,还要特别注意执行人和回传照片的存储。回传照片不要存 base64,那是纯灾难,存相对路径,图片文件走上传目录。
CREATE TABLE `sacrifice_order` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `order_no` varchar(32) NOT NULL COMMENT '业务订单号', `member_id` int unsigned NOT NULL, `hall_id` int unsigned NOT NULL, `pack_id` int unsigned NOT NULL, `pay_status` tinyint NOT NULL DEFAULT 0 COMMENT '0未支付 1已支付 2已退款', `service_status` tinyint NOT NULL DEFAULT 0 COMMENT '0待支付 1已支付待执行 2执行中 3已完成 4已取消', `executor_id` int unsigned NOT NULL DEFAULT 0 COMMENT '执行人ID', `photo_back_url` varchar(500) NOT NULL DEFAULT '', `fail_reason` varchar(255) NOT NULL DEFAULT '' COMMENT '履约失败原因', `create_time` int unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_no` (`order_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='代祭订单表';order_no不要用数据库自增 ID 直接暴露给用户,生成规则建议用日期加随机串,比如202504081230150001,既是订单号又能人工读日期。fail_reason字段通常是在客户投诉后由管理员填写的,没它也可以运行,但出现纠纷时没有留痕,会非常被动。
4.4 字段设计的取舍:别过度设计
网上公墓这种垂直业务,最容易出现的反面设计是“把所有业务塞进一张大表”:字段叫object_type、object_id,靠程序逻辑区分这是纪念堂还是订单。前期开发快,后期加权限、加报表时所有查询都绕不开 type 判断,索引也没法高效利用。
取舍标准只有一个:字段是否参与查询、统计或权限判断。参与的,拆成独立表;不参与的,比如用户偏好设置、纪念堂自定义 CSS 变量,可以放 JSON 字段。不要为了“看起来专业”把每个小标签都建一张表,那会让一次建堂要 join 七八张表,完全没有必要。
5. 网上公墓上线期最容易翻车的五个坑:现象、原因、处理方法
这套系统与其他业务系统最大的不同是:高峰期高度集中,清明节前后一周的流量可能占全年一半;同时内容敏感,一旦展示出错没有后悔药。以下五个坑是我在多套同类源码里反复见到的。
5.1 高峰祭祀时纪念堂页面白屏,刷新后恢复
现象:清明当天上午,热门纪念堂页面打开先是转圈,然后白屏,刷新一次又能出来。原因有两个:一是页面实时查数据库,高并发下连接池被打满;二是墓碑图、供品图全部走应用服务器,没有做动静分离。
处理办法:纪念堂详情页做静态化缓存,页面骨架和逝者信息缓存半小时;祭拜记录写入走队列,不回写页面;图片全部迁移到对象存储加 CDN。如果源码里所有图片都在本地目录,至少要给 upload 目录单独配 Nginx 别名,别让 PHP 进程处理图片请求。
5.2 支付回调漏单,用户付款后订单还是待支付
现象:用户在代祭服务里付款成功,后台订单状态不动,客服只能手工改单。支付回调对很多项目来说是个黑匣子,日志里什么都看不到。
原因主要是回调处理没做幂等,或者回调地址被防火墙拦截。第一次回调处理成功后,没有给支付平台返回固定应答,平台重试时程序又执行一遍,订单状态被覆盖成异常。
处理办法:回调接口第一行就检查订单当前支付状态,已支付直接返回成功,不重复更新:
if ($order['pay_status'] == 1) { echo 'success'; exit; }然后才是金额校验、签名校验、更新订单。金额校验不能只看“等于”,要允许数据库里的价格和支付回调金额严格相等,差一分都算异常。生产环境还要加主动对账,每天定时拉取支付平台账单与本地订单比对,出现不一致时自动告警,这才是兜底方案。
5.3 留言区出现不合规内容,外勤接到投诉电话
现象:纪念堂公开留言下突然冒出一条广告或不当言论,家属直接投诉到线下服务处。
原因:前台只做了简单的关键词过滤,没有审核流。关键词可以绕过,人工才是最后一道闸。
处理办法:留言写入时状态改为“待审核”,运营后台通过后才对外展示。敏感词库要同时覆盖中文、拼音以及常见变体,但别指望库能挡全部,审核列表必须有人工处理能力。用户上传的祭祀照片也一样,先审后发。这套流程做进去之后,日常运维压力反而小了,因为前台根本看不到未过审内容。
5.4 演示环境被当成生产环境用,测试数据撒了一地
现象:本地联调时建的“示例档案”出现在公网墓碑二维码里,扫码进去满屏测试占位数据。
原因:上线时只改了数据库连接,没把演示数据清理干净;二维码已经印刷,线上无法快速替换。
处理办法:从第一天起做环境隔离,演示数据库和生产数据库的表前缀都可以不同;凡是用于演示的纪念堂,命名统一加demo-前缀,封面上也打水印。二维码绑定关系上线前要全量导出一份清单,核对每个二维码是否都对应有效纪念堂,宁可漏绑,不要错绑。
5.5 域名备案与访问合规:不提前做,后面只能停站等
现象:域名接入公网后访问被服务商提示“未备案”,移动端 H5 打开直接被拦截;已经做了小程序的,接口域名也会被要求必须 HTTPS 加备案。
原因:上线前一个月没有备案,域名和服务器准备好了才发现合规手续不在流程里。
处理办法:域名备案从准备资料到下发通常要几周,项目开工第一周就要提交。和客户签合同时把“备案由谁负责、周期多久”写清楚,不要默认是技术人员的事。对外服务的 H5 页面强制 HTTPS,所有资源引用改成相对路径或协议自适应,避免页面出现混合内容拦截。这一整套不是技术上的难事,流程前移就行。
6. 验证一次完整的祭祀闭环:从建馆到照片回传的验收脚本
只看代码不跑通闭环,等于没验收。我给自己定的标准是:必须在本地把“建馆 → 提交代祭订单 → 模拟支付回调 → 执行人回传照片 → 前台展示回传”整条链路走一遍,任何一节断了都不过关。
6.1 一条完整链路:用 Python 脚本模拟真实请求
下面的脚本按常见接口路径来写,实际使用时替换成源码包里对应的路由即可:
import requests, time, hashlib base_url = 'http://127.0.0.1:8080' # 先登录后台拿到管理员 token,换取执行人和用户身份 token = '你的登录凭证' # 1. 创建纪念堂 r = requests.post(base_url + '/api/hall/create', json={ 'deceased_name': 'demo-001', 'birth_date': '1950-01-01', 'death_date': '2024-03-10', 'hall_theme': 'classic' }, headers={'Authorization': 'Bearer ' + token}) assert r.json()['code'] == 0, '建馆失败' hall_id = r.json()['data']['hall_id'] # 2. 发起代祭订单 r2 = requests.post(base_url + '/api/sacrifice/order', json={'hall_id': hall_id, 'pack_id': 3, 'mobile': '13800000000'}, headers={'Authorization': 'Bearer ' + token}) assert r2.json()['code'] == 0, '下单失败' order_no = r2.json()['data']['order_no'] # 3. 模拟支付回调,注意老系统多数用 MD5 拼串签名 params = {'order_no': order_no, 'pay_status': 'success', 'amount': '99.00'} params['sign'] = hashlib.md5( ('%s|%s|%s|%s' % (order_no, 'success', '99.00', '回调密钥')).encode() ).hexdigest() r3 = requests.post(base_url + '/api/pay/notify', data=params) assert r3.text == 'success', '支付回调失败' # 4. 执行人上传回传照片 files = {'file': ('back_photo.jpg', open('back_photo.jpg', 'rb'), 'image/jpeg')} r4 = requests.post(base_url + '/api/order/upload-photo', data={'order_no': order_no}, files=files, headers={'Authorization': 'Bearer ' + token}) assert r4.json()['code'] == 0, '照片回传失败' print('闭环验证通过')脚本里最关键的是第 3 步:支付回调必须返回固定文本,程序才认为是终态;如果回调里还用旧版 MD5 签名,新项目建议至少升级成 HMAC-SHA256,密钥放到配置文件而不是代码里。
6.2 演示环境的数据翻新:别让客户打开全是空堂
给客户演示时最尴尬的不是功能缺陷,而是纪念堂页面空无一物。我这里说的数据翻新不是造假:用程序批量生成一批带明显“示例”标签的测试档案,时间跨度放在过去 180 天,让祭拜量和留言量的分布接近真实曲线。批量生成时直接写 SQL 比调接口快得多,但注意create_time不要全部集中在同一秒,否则列表排序看起来会非常假。
交付时一定要把生产环境和演示环境的二维码彻底分开,我见过太多“测试档案刻上墓碑”的返工事故,那比代码 bug 贵得多。后来我的习惯是:凡涉及二维码和线下绑定的项目,上线前必须导出一份“二维码编号 → 纪念堂ID → 绑定时间”的对照表,逐一核对后才算交付完成。希望这条习惯也能帮到你。
本文还有配套的精品资源,点击获取