目录结构
public/template/clientarea/{模板标识}/
├── {模板标识}.php # 模板配置文件
├── clientarea.html # 仪表盘/首页
├── login.html # 登录页面
├── register.html # 注册页面
├── hostlist.html # 产品列表
├── host.html # 产品详情
├── orders.html # 订单列表
├── order.html # 订单详情
├── addfunds.html # 充值页面
├── balanceLog.html # 余额日志
├── profile.html # 个人资料
├── realname.html # 实名认证
├── verified.html # 实名认证检测
├── ticketlist.html # 工单列表
├── ticket.html # 工单详情
├── submitaticket.html # 提交工单
├── common/ # 公共组件
│ ├── header.html # 页面头部
│ ├── footer.html # 页面底部
│ ├── meta.html # Meta 标签
│ ├── script.html # 脚本引用
│ ├── sidenav.html # 侧边导航
│ └── captcha.html # 验证码组件
└── assets/ # 静态资源(可选)
├── css/
├── js/
└── images/
路由规范
| 路由 | 对应模板 | 说明 |
|---|
/clientarea | clientarea.html | 仪表盘 |
/login | login.html | 登录 |
/register | register.html | 注册 |
/clientarea/hostlist | hostlist.html | 产品列表 |
/clientarea/host/{id} | host.html | 产品详情 |
/clientarea/orders | orders.html | 订单列表 |
/clientarea/order/{id} | order.html | 订单详情 |
/clientarea/addfunds | addfunds.html | 充值 |
/clientarea/balanceLog | balanceLog.html | 余额日志 |
/clientarea/profile | profile.html | 个人资料 |
/clientarea/realname | realname.html | 实名认证 |
/clientarea/verified | verified.html | 实名认证检测 |
/clientarea/ticketlist | ticketlist.html | 工单列表 |
/clientarea/ticket/{id} | ticket.html | 工单详情 |
/clientarea/submitaticket | submitaticket.html | 提交工单 |
/clientarea/page/{name} | {name}.html | 自定义页面 |
配置文件
<?php
function {模板标识}_MetaData()
{
return [
"DisplayName" => "用户中心模板",
"APIVersion" => "1.0.0",
"HelpDoc" => "http://example.com"
];
}
function {模板标识}_ConfigOptions()
{
return [
[
'key' => 'site_title',
'title' => '网站标题',
'type' => 'input',
'default' => '',
'options' => [],
'tip' => '显示在浏览器标签页',
],
[
'key' => 'footer',
'title' => '页脚内容',
'type' => 'textarea',
'default' => '',
'options' => [],
'tip' => '支持HTML',
],
[
'key' => 'theme',
'title' => '主题风格',
'type' => 'select',
'default' => 'light',
'options' => [
'light' => '浅色',
'dark' => '深色',
],
'tip' => '选择配色方案',
],
];
}
配置访问:{$config.clientarea_meta.xxx}
字段类型:input(单行)、textarea(多行)、select(下拉)
全局变量
| 变量 | 说明 |
|---|
$site.name | 站点名称 |
$site.favicon | 站点图标 |
$site.version | 站点版本 |
$config | 系统配置 |
$user.id | 用户ID |
$user.nickname | 昵称 |
$user.email | 邮箱 |
$user.mobile | 手机号 |
$user.avatar | 头像URL |
$user.money | 余额 |
$Request.token | CSRF Token |
页面变量速查
clientarea.html(仪表盘)
| 变量 | 说明 |
|---|
$runningServices | 运行中服务数 |
$accountBalance | 账户余额 |
$pendingTickets | 待处理工单数 |
$weekConsumption | 近7天消费 |
$securityStatus | 安全状态 |
$recentServices | 最近服务列表 |
$recentOrders | 最近订单列表 |
hostlist.html(产品列表)
| 变量 | 说明 |
|---|
$hosts | 产品列表(分页) |
$p.id | 产品ID |
$p.domain | 主机名/域名 |
$p.status | 状态 |
$p.product.product_name | 产品名称 |
$p.priceMatrix | 续费周期价格 |
$page | 当前页码 |
$lastPage | 总页数 |
host.html(产品详情)
| 变量 | 说明 |
|---|
$host.id | 产品ID |
$host.domain | 主机名 |
$host.status | 状态 |
$host.nextduedate | 到期时间 |
$host.product.product_name | 产品名称 |
$host.product.billing_type | 计费类型 |
$moduleButtons | 模块操作按钮 |
$priceMatrix | 续费价格 |
orders.html(订单列表)
| 变量 | 说明 |
|---|
$orders | 订单列表 |
$order.ordernum | 订单号 |
$order.amount | 金额 |
$order.status | 状态 |
$order.type | 类型 |
$order.product.product_name | 产品名称 |
$page | 当前页码 |
$lastPage | 总页数 |
order.html(订单详情)
| 变量 | 说明 |
|---|
$order.id | 订单ID |
$order.ordernum | 订单号 |
$order.amount | 金额 |
$order.status | 状态 |
$order.create_time | 创建时间 |
$order.pay_time | 支付时间 |
$order.payment | 支付方式 |
$order.product.product_name | 产品名称 |
$pay_channel | 支付渠道列表 |
ticketlist.html(工单列表)
| 变量 | 说明 |
|---|
$tickets | 工单列表 |
$ticket.id | 工单ID |
$ticket.tid | 工单编号 |
$ticket.title | 标题 |
$ticket.user_side_status | 用户侧状态 |
$ticket.priority | 优先级 |
$ticket.category.name | 部门名称 |
$page | 当前页码 |
$lastPage | 总页数 |
ticket.html(工单详情)
| 变量 | 说明 |
|---|
$ticket.id | 工单ID |
$ticket.tid | 工单编号 |
$ticket.title | 标题 |
$ticket.content | 内容 |
$ticket.user_side_status | 用户侧状态 |
$ticket.priority | 优先级 |
$replies | 回复列表 |
$reply.content | 回复内容 |
$reply.is_staff | 是否为客服回复 |
$reply.create_time | 回复时间 |
profile.html(个人资料)
| 变量 | 说明 |
|---|
$user.id | 用户ID |
$user.nickname | 昵称 |
$user.email | 邮箱 |
$user.mobile | 手机号 |
$user.avatar | 头像URL |
$user.money | 余额 |
$user.group.name | 用户组名称 |
$user.create_time | 注册时间 |
$securityStatus | 安全状态 |
$countries | 国家/地区列表 |
realname.html(实名认证)
| 变量 | 说明 |
|---|
$realNameStatus | 认证状态 |
$idv.name | 真实姓名 |
$idv.id_card_no | 证件号码(脱敏) |
$idv.reject_reason | 拒绝原因 |
$used | 已使用认证次数 |
$plugin.free_times_total | 免费认证次数 |
$plugin.fee_after_free | 超出免费次数后的费用 |
addfunds.html(充值)
| 变量 | 说明 |
|---|
$user.money | 当前余额 |
$paymentMethods | 可用支付方式 |
$minAmount | 最小充值金额 |
$maxAmount | 最大充值金额 |
$rechargeBonuses | 充值赠送规则 |
balanceLog.html(余额日志)
| 变量 | 说明 |
|---|
$user.money | 当前余额 |
$increase | 较上月增加金额 |
$logs | 余额变动记录 |
$log.type | 类型 |
$log.amount | 变动金额 |
$log.before | 变动前余额 |
$log.after | 变动后余额 |
$log.remark | 备注 |
模板语法
<!-- 变量输出 -->
{$variable}
{$variable|default='默认值'}
<!-- 条件判断 -->
{if $condition}
...
{elseif $other}
...
{else}
...
{/if}
<!-- Switch -->
{switch name="$variable"}
{case value="a"}...{/case}
{default}...{/default}
{/switch}
<!-- 循环 -->
{foreach $list as $item}
{$item.name}
{/foreach}
{volist name="list" id="item" key="k"}
{$k} - {$item.name}
{/volist}
<!-- 包含文件 -->
{include file="clientarea/{模板标识}/common/header" /}
<!-- PHP 代码块 -->
{php}
$var = 'value';
{/php}
<!-- 使用函数 -->
{$var|htmlspecialchars}
{$time|date='Y-m-d'}
页面结构
普通页面
{php}
$title='页面标题';
{/php}
{include file="clientarea/{模板标识}/common/header" /}
<div class="container px-3 py-4">
<!-- 页面内容 -->
</div>
{include file="clientarea/{模板标识}/common/footer" /}
登录/注册页面(独立页面)
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>{$site.name|default='系统'} - 登录</title>
<link href="__CDN__/assets/css/frontend{$Think.config.app_debug?'':'.min'}.css?v={$Think.config.site.version|htmlentities}" rel="stylesheet">
<script type="text/javascript">
var require = { config: {$config|json_encode} };
</script>
</head>
<body>
<form id="login-form" method="POST" action="">
{:token()}
<input type="text" name="account" placeholder="账号">
<input type="password" name="password" placeholder="密码">
<!--@IndexLoginFormEnd-->
<button type="submit">登录</button>
</form>
<script src="__CDN__/assets/js/require{$Think.config.app_debug?'':'.min'}.js"
data-main="__CDN__/assets/js/require-frontend{$Think.config.app_debug?'':'.min'}.js?v={$site.version|htmlentities}"
defer></script>
</body>
</html>
注册页面特殊标记:<!--@IndexRegisterFormEnd-->
常用 API 接口
订单相关
| 接口 | 方法 | 参数 | 说明 |
|---|
/api/order/channels | GET | - | 支付方式列表 |
/api/order/createRechargeOrder | POST | amount, pay_id | 创建充值订单 |
/api/order/createRenewOrder | POST | host_id, period_key | 创建续费订单 |
/api/order/pay | POST | ordernum, payment | 订单支付 |
/api/order/cancel | POST | ordernum | 取消订单 |
主机/产品相关
| 接口 | 方法 | 参数 | 说明 |
|---|
/api/host/control | POST | host_id, action | 主机控制(boot/reboot/shutdown) |
/api/host/notes | POST | host_id, notes | 保存主机备注 |
用户相关
| 接口 | 方法 | 参数 | 说明 |
|---|
/api/user/profile | POST | nickname, bio 等 | 更新用户资料 |
/api/user/changepwd | POST | oldpassword, newpassword | 修改密码 |
/api/user/avatar | POST | avatar | 更新头像 |
/index/user/login | POST | account, password, captcha | 用户登录 |
/index/user/register | POST | username, email, password 等 | 用户注册 |
/index/user/logout | POST | - | 退出登录 |
工单相关
| 接口 | 方法 | 参数 | 说明 |
|---|
/index/clientarea/submitaticket | POST | title, department, priority, description 等 | 提交工单 |
/clientarea/replyticket | POST | ticket_id, content | 回复工单 |
/clientarea/closeticket | POST | ticket_id | 关闭工单 |
附件/上传
| 接口 | 方法 | 参数 | 说明 |
|---|
/index/attachment/upload | POST | file (multipart/form-data) | 文件上传 |
调试
{php}
print_r($user);
var_dump($order);
{/php}
附录
Bootstrap Icons 常用图标
| 图标 | 用途 |
|---|
bi bi-speedometer2 | 仪表盘 |
bi bi-server | 服务器/产品 |
bi bi-wallet2 | 财务/余额 |
bi bi-gear | 设置 |
bi bi-headset | 工单/客服 |
bi bi-person | 用户 |
bi bi-cart-plus | 购买 |
bi bi-check-circle | 成功/完成 |
bi bi-inbox | 空状态 |
颜色参考
| 颜色 | 类名 | 用途 |
|---|
| 主色 | primary / #0d6efd | 主要操作、链接 |
| 成功 | success / #198754 | 成功状态、运行中 |
| 警告 | warning / #ffc107 | 警告状态、待处理 |
| 危险 | danger / #dc3545 | 错误、已暂停 |
| 信息 | info / #0dcaf0 | 提示信息 |
chat_bubble_outline 评论