简介:一份基于AXMB-GY v2.0的全开源爱希彩虹易支付模板,专为需要搭建或美化彩虹易支付系统的站长与开发者设计,重点重构了用户中心、登录、注册、找回密码及支付页面,整体采用简洁轻量级风格,兼顾视觉体验与加载性能。代码全开源,具备较高的兼容性和稳定性,适合具备一定PHP开发基础的人员进行定制与二次开发。包体为RAR压缩包,共179个文件,压缩后仅4.46MB,其中JS脚本71个负责前端交互与校验,PHP模板32个控制页面渲染,CSS样式表23个定义视觉风格,辅以图片、字体和SVG图标素材,覆盖前端交互、后端逻辑、页面布局与素材展示多个层面;模板目录结构清晰,便于按模块检索和替换。目前已有187人浏览学习,适合需要快速获得整套易支付模板、参考其页面美化和组件组织的开发者;使用前建议备份原有user目录,以便安全切换与回退。
1. 从一套 CSS 文件看彩虹易支付的页面层解耦
做易支付二次开发的开发者,第一眼看到这套 AXMB-GY v2.0 全开源爱希模板,通常会被它的静态资源清单吸引:icons.min.css、app.css、animate.min.css、sweetalert2.min.css…… 十份样式文件把页面层需要的基础能力全部列齐,说明作者是先把资源体系理清楚,再去做页面视觉。在替换 user 目录之前,我先把原目录完整打了一个 tar 包,这是成本最低的回滚手段。这套模板将用户中心、登录、注册、找回密码和支付页面的视图层全部重构,样式资源统一收敛成一组可替换的静态基线,适合跑着彩虹易支付、想换皮又不想动核心支付逻辑的 PHP 开发者,也适合想理解一套易支付模板语言如何组织页面的新手直接仿写。
2. 静态资源基线与页面骨架改造
2.1 十份 CSS 文件在模板里的分工
这套模板携带的样式文件,对应一套典型的后台管理型页面资源组合。理解每份文件的职责,才能在二次开发时不至于改错地方。我按实际作用域整理了一份分工表:
| 文件 | 作用域 | 职责 |
|---|---|---|
| icons.min.css | 全局 | 图标字体,覆盖菜单、按钮、步骤条 |
| animate.min.css | 全局 | 元素进出场动画,用于弹窗和页面切换 |
| sweetalert2.min.css | 弹层 | 支付结果、删除确认等状态弹窗 |
| quill.bubble.css / quill.snow.css | 编辑区 | 富文本编辑器的两套主题皮肤 |
| bootstrap-datepicker.min.css | 表单 | 日期选择器,账单与对账筛选常用 |
| select2.min.css | 表单 | 下拉搜索增强,通道和商户选择 |
| fullcalendar.min.css | 数据展示 | 日历视图,适合每日流水总览 |
| bootstrap-chosen.css | 表单 | 另一种下拉增强方案,兼容旧页面 |
| app.css | 全局 | 模板自己的覆盖层 |
从表格可以看出来,模板没有把功能样式全部揉进一个文件里,而是保留了原库文件的独立性。这种做法的好处是升级某个组件时只需要替换对应 CSS 文件,坏处是引用的顺序一旦变化,样式表现就会漂移,所以 head 区域的引用顺序是有讲究的。
2.2 head 资源的引入顺序与路径常量
在模板里新建或改写页面时,head 区域的资源引入顺序建议保持一致性。我在这套模板里使用的顺序如下:
<link rel="stylesheet" href="__TMPL__/css/icons.min.css"> <link rel="stylesheet" href="__TMPL__/css/animate.min.css"> <link rel="stylesheet" href="__TMPL__/css/bootstrap-datepicker.min.css"> <link rel="stylesheet" href="__TMPL__/css/select2.min.css"> <link rel="stylesheet" href="__TMPL__/css/fullcalendar.min.css"> <link rel="stylesheet" href="__TMPL__/css/sweetalert2.min.css"> <link rel="stylesheet" href="__TMPL__/css/quill.snow.css"> <link rel="stylesheet" href="__TMPL__/css/quill.bubble.css"> <link rel="stylesheet" href="__TMPL__/css/bootstrap-chosen.css"> <link rel="stylesheet" href="__TMPL__/css/app.css">引入顺序遵循一个原则:功能型样式先加载,覆盖型样式后加载。sweetalert2、select2、quill 这类组件库必须放在 app.css 前面,否则 app.css 中针对按钮和表单的全局覆盖会被组件库自带样式抢先锁定,模板的主色和圆角就会失效。__TMPL__是模板路径常量,渲染时会被替换为模板目录的绝对 URL。我建议所有资源引用都写这个常量而不写相对路径,因为彩虹易支付的页面经常嵌入 iframe,相对路径在这种场景下会以父页面 URL 为基准解析,导致样式文件 404。
2.3 版本参数与浏览器缓存
模板里所有 CSS 引用后面,我建议都挂上版本参数,这是静态资源发布时的常规做法:
<link rel="stylesheet" href="__TMPL__/css/app.css?v=20250601">这个细节在支付场景里尤其重要。支付页是用户高频进出的页面,浏览器对 CSS 的缓存策略很激进,改动样式后如果不更新版本号,用户看到的永远是旧视觉。版本参数可以用发布日期区分,也可以在每次样式改动时手动递增,强制客户端重新拉取文件。如果站点开启了 Nginx 层缓存,还需要连同缓存 key 一起刷新,否则版本参数会被缓存策略忽略。
2.4 app.css 的覆盖规律与冲突排查
app.css 是整套模板的自定义核心,它的体积通常不大,但针对原版框架只做三件事:主色替换、卡片圆角、表单控件尺寸统一。代码结构大致如下:
body.tpl-axmb .btn-primary { background: linear-gradient(135deg, #6366f1, #8b5cf6); border: none; border-radius: 8px; } body.tpl-axmb .table > tbody > tr > td { padding: 12px 16px; border-top: 1px solid #f1f5f9; }重点在body.tpl-axmb前缀,这是模板预留的命名空间。有了这个前缀,app.css 里的全局选择器就不会污染同一域名下其他非模板页面。排错的时候,打开浏览器开发者工具的 Computed 面板,如果看到目标属性被删除线划掉,说明 app.css 选择器的优先级不够,解决办法是把前缀选择器往上提升一层,例如在页面根节点加上class="tpl-axmb",然后直接把 body 前缀换成.tpl-axmb。
3. 登录、注册与找回密码页面的模板化
3.1 认证页面从表格布局到弹性布局
彩虹易支付原版认证页用的是列表铺排的方式,输入框从上往下堆叠。这套模板把认证流程收敛进一张居中的卡片,卡片内使用弹性布局,背景改成渐变,整个页面的视觉重心集中在表单区域。整套布局属于典型的响应式页面设计模板,在手机端会自动压缩卡片间距,不需要单独写移动端样式。替换时最关键的一点是保留原表单的提交地址和字段名,只改外层视觉结构:
<div class="auth-card"> <div class="auth-header"> <i class="iconfont icon-shield"></i> <h3>商户登录</h3> </div> <form action="{:url('user/login')}" method="post" class="auth-form"> <div class="form-group"> <input type="text" name="username" class="form-control" placeholder="用户名" required> </div> <div class="form-group"> <input type="password" name="password" class="form-control" placeholder="密码" required> </div> <div class="form-group captcha-line"> <input type="text" name="verify_code" class="form-control" placeholder="验证码"> <img src="{:captcha_src()}" class="captcha-img" onclick="this.src='{:captcha_src()}&t='+Date.now()"> </div> <button type="submit" class="btn btn-primary btn-block">登 录</button> </form> </div>{:url('user/login')}是 ThinkPHP 模板引擎的动态路由函数,渲染时会按当前站点的伪静态配置生成真正的提交地址。这个地方不要硬编码成/index.php/user/login,因为站点部署在子目录或开启伪静态之后,硬编码地址会直接失效。验证码图片的onclick刷新逻辑要保留,后面的Date.now()参数是为了破坏浏览器对验证码图片的缓存,否则点击刷新会一直显示同一张图。
3.2 找回密码的步骤条与模板变量
找回密码页面在原系统里是通过同一个控制器方法配合步骤参数渲染的,模板层只需要把步骤变量转换成可视化步骤条,不需要修改任何控制器代码:
<div class="steps"> <div class="step-item {if $step >= 1}active{/if}"> <span class="step-num">1</span> <span class="step-text">验证账号</span> </div> <div class="step-item {if $step >= 2}active{/if}"> <span class="step-num">2</span> <span class="step-text">重置密码</span> </div> <div class="step-item {if $step >= 3}active{/if}"> <span class="step-num">3</span> <span class="step-text">完成</span> </div> </div>{if $step >= 1}是模板引擎的直出判断,服务端渲染时就已经确定高亮状态,不需要前端再跑脚本。使用这个语法时要注意变量$step必须已经在控制器中被 assign,如果变量没被赋值,表达式会默认判断为假,步骤条会一直停在初始状态。改页面时如果发现步骤条不亮,优先去控制器里查 step 变量的赋值位置和传入时机,而不是查 CSS。
3.3 用户中心的侧边栏与统计卡片
用户中心的改动重点在侧边栏导航和数据总览。新模板把菜单按功能分组,并给每组加上图标,当前激活项用左侧色条标注。激活逻辑依然依赖模板变量的映射,这是模板语言里比较常用的做法:
<ul class="sidebar-menu"> <li class="menu-item {if $action == 'index'}active{/if}"> <a href="{:url('user/index')}"> <i class="iconfont icon-home"></i> <span>控制台</span> </a> </li> <li class="menu-item {if $action == 'order'}active{/if}"> <a href="{:url('user/order')}"> <i class="iconfont icon-list"></i> <span>订单记录</span> </a> </li> <li class="menu-item {if $action == 'withdraw'}active{/if}"> <a href="{:url('user/withdraw')}"> <i class="iconfont icon-wallet"></i> <span>提现管理</span> </a> </li> </ul>$action变量由控制器渲染页面时传入,含义是当前请求对应的方法名。侧边栏使用精确匹配来做高亮,每次进到对应页面时状态都是确定的。用户中心首屏的统计卡片区域,常用模板变量对应关系如下,二次开发时可以直接对照:
| 模板变量 | 含义 | 格式化方式 |
|---|---|---|
$user.money | 账户余额 | `{$user.money |
$today_income | 今日收入 | `{$today_income |
$order_count | 订单总数 | {$order_count} |
$success_rate | 支付成功率 | {$success_rate}% |
这些变量是控制器在渲染用户中心时已经赋予模板的,模板层只负责展示。变量名在不同版本的彩虹易支付系统中可能有差异,替换模板后如果某块数据空白,先到控制器文件里确认变量名是否一致,再决定是改模板还是改控制器。
4. 收银台渲染与支付状态反馈层
4.1 订单摘要面板的变量映射
支付页面最核心的信息是订单摘要。新模板对收银台的布局做了较大调整,把订单摘要和二维码放在同一个视口高度内,用户不需要滚动就能看到全部信息。订单摘要的渲染直接使用控制器传入的订单对象:
<div class="order-panel"> <div class="order-title"> <span class="order-status">待支付</span> <span class="order-no">订单号:{$order.trade_no}</span> </div> <div class="order-amount"> <span class="amount-symbol">¥</span> <span class="amount-num">{$order.amount|number_format=2}</span> </div> <div class="order-info"> <p>商品名称:{$order.product_name}</p> <p>创建时间:{$order.create_time|date='Y-m-d H:i:s'}</p> </div> </div>{$order.amount|number_format=2}使用模板引擎内置过滤器对金额做格式化,输出时自动保留两位小数,避免 PHP 端提前处理带来的类型精度问题。{$order.trade_no}直接输出订单号,模板引擎会自动做 HTML 实体转义,所以页面上不需要再写额外的转义函数。这个面板改完后,只要控制器输出的字段名不变,支付流程就不会受影响。
4.2 支付方式切换与二维码更新
支付方式的切换在模板里是一个典型的请求-替换交互:点击 tab 按钮、请求新二维码、替换图片。HTML 结构保留原系统的通道标记,前端通过自定义属性区分通道类型:
<div class="pay-tabs"> <button class="pay-tab active">function checkPayStatus(tradeNo) { $.get('/index.php/pay/status', {trade_no: tradeNo}, function (resp) { if (resp.code === 1) { Swal.fire({ title: '支付成功', icon: 'success', confirmButtonText: '查看订单', timer: 3000 }).then(function () { window.location.href = resp.url; }); } else { setTimeout(function () { checkPayStatus(tradeNo); }, 2000); } }, 'json'); }sweetalert2.min.css在这一层的价值是保证弹层在移动端和 PC 端表现一致。Swal.fire的timer参数控制自动关闭时间,设成 3000 表示弹窗出现三秒后自动关闭链接;confirmButtonText决定底部按钮文案,用户手动点击时立即跳转,不需要等倒计时结束。轮询间隔我习惯设置为 2000 毫秒,对网关压力比 1000 毫秒小,用户的等待体感差异不大。这个交互在接入扫码支付通道时尤其有用,因为用户扫码之后不一定会主动回到页面刷新。
4.4 模板层与服务端的职责边界
在支付页这个敏感场景里,模板能做的事需要明确界限。CSS 负责搭建页面骨架,JavaScript 负责请求支付状态接口并渲染结果,订单金额计算、验签、状态修改这些逻辑必须留在原控制器里。模板文件替换范围应该限定在视图层和静态资源目录,不要把原版的PayController、NotifyController相关文件一并覆盖。很多支付异常问题都出在改模板时不小心动到了服务端文件,这一点比样式错乱更难排查,因为接口报错会被前端脚本静默吞掉。
5. 替换 user 目录前要做的核对清单
5.1 备份、比对、回滚三步走
替换前的备份不要只做复制粘贴,要带时间戳并保留目录权限,命令行操作是最可靠的:
cp -a /www/wwwroot/pay/user /www/wwwroot/pay/user.bak.$(date +%Y%m%d) diff -rq /www/wwwroot/pay/user.bak.$(date +%Y%m%d) /www/wwwroot/pay/usercp -a会保留文件属主、权限和符号链接,PHP 项目上传目录的执行权限一旦丢失,静态文件会直接返回 403,用户头像和支付凭证图片都会挂掉。第二行diff -rq只输出两个目录的文件差异列表,不输出内容变更,适合在替换前确认模板覆盖范围是否与预期一致。看到输出结果后,重点核对是否有原版核心 PHP 文件被同名覆盖。
5.2 用开发者工具确认样式链路
替换后先不要点击任何按钮,打开浏览器开发者工具 Network 面板,强制刷新页面,过滤 CSS 类型,检查模板引用的样式文件是否全部返回 200。如果发现 404,优先排查__TMPL__常量解析出来的路径是否包含站点子目录。很多站点部署在域名二级目录下,ThinkPHP 的模板常量替换规则需要额外适配。遇到样式错乱但 Network 面板全绿时,再切到 Elements 面板看具体元素的计算样式,确认是 app.css 的覆盖规则没生效,还是组件库自带样式优先级更高。
5.3 支付接口异常时的快速定位
如果收银台能正常渲染但支付接口报 500,直接切到 Console 面板看是否有路由规则或跨域报错。二维码图片区域空白时,在 Console 输入以下代码,判断接口返回的 base64 数据是否完整:
atob('粘贴接口返回的data部分')如果atob能正常解析出乱码字符,说明 base64 数据是完整的,问题出现在渲染时没有拼接data:image/png;base64,前缀;如果抛异常,说明接口返回被截断或包含多余字符,需要回到服务端查日志。这个判断方法比盯着页面猜测快得多,批量接入新支付通道时可以直接复用这一套排查链路。
本文还有配套的精品资源,点击获取