适用场景
适合中后台管理系统、会员运营系统、商品交易系统、内容平台和多端渠道配置类项目。
支持从基础框架起步,再按业务逐步扩展。
快速开发后台框架的项目说明、功能介绍、开发规范与示例代码。
壹站 onezan-admin 是一套面向后台管理与业务扩展场景的开发框架,覆盖用户、权限、商品、订单、支付、渠道、内容、素材、系统设置等常用能力,并提供独立的交互式接口文档与图标资源入口。
壹站 onezan-admin 适用于企业后台、业务运营平台、内容管理平台和交易管理平台等场景。项目采用前后端分离结构,内置后台管理、业务模块、渠道中心和基础配置能力,可作为新项目的统一底座继续扩展。
适合中后台管理系统、会员运营系统、商品交易系统、内容平台和多端渠道配置类项目。
支持从基础框架起步,再按业务逐步扩展。
内置用户、角色权限、商品、订单支付、渠道配置、内容、素材、系统设置和数据看板等能力。
接口参数、请求体和在线调试能力单独维护在交互式接口文档中。
服务端采用分层目录结构,后台前端按页面、接口、组件、类型和布局拆分,便于长期维护。
目录、命名和职责边界保持一致,便于新增模块和多人协作。
文档中心用于项目说明、开发规范和示例代码,接口调试与参数说明通过交互式接口文档查看。
图标资源通过图标文档集中维护。
当前系统已经包含后台常用管理能力和交易相关基础能力,可直接用于项目初始化或继续承接行业业务扩展。
| 功能项 | 当前覆盖内容 | 说明 |
|---|---|---|
| 用户管理 | 用户列表、等级、实名认证、余额、余额流水 | 适合继续扩展会员体系、积分体系和账户体系。 |
| 权限与管理员 | 角色、权限码、管理员、菜单访问控制 | 适合继续扩展部门、岗位和细粒度权限。 |
| 商品管理 | 商品列表、编辑、上下架、复制、展示信息维护 | 适合继续扩展 SKU、库存、营销活动和价格体系。 |
| 订单与支付 | 订单管理、支付单、退款处理、财务流水 | 适合继续扩展售后、结算、对账和账单能力。 |
| 渠道管理 | 渠道接口、支付、通知配置和模板同步 | 适合继续扩展更多终端和第三方平台。 |
| 应用中心 | addon 模块开关、付费会员、优惠券 | 适合继续扩展分销、代理、秒杀、抽奖、积分兑换和 AI 能力。 |
| 内容、素材与系统 | 内容分类、内容管理、素材管理、协议与系统设置 | 适合继续扩展帮助中心、专题页和运营位配置。 |
服务端目录为 e:\wwwroot\onezan.test\api,依赖 PHP 8.0+ 与 Composer。站点根目录建议指向 api/public,便于统一访问后台、前台和文档入口。
cd e:\wwwroot\onezan.test\api
composer install
# Web 根目录指向 api/public
# 然后通过域名访问:
# http://onezan.test/
# 常用命令
php think reset:admin:password
php think order:auto-cancel
php think admin:cleanup-operation-logs
# 伪静态规则
location ~* (runtime|application)/{
return 403;
}
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?s=$1 last; break;
}
}
常用命令包含管理员密码重置、超时订单处理和后台操作日志清理。
后台前端目录为 e:\wwwroot\onezan.test\admin,依赖 Node.js 20.19.0+。开发模式下通过服务端域名访问后台接口。
cd e:\wwwroot\onezan.test\admin npm install npm run dev # 质量检查 npm run lint npm run stylelint npm run build:type npm run build
开发环境通常通过 VITE_API_URL=http://onezan.test 访问服务端。
data/onezan.sql 初始化数据库。api/public。php think reset:admin:password。/apidoc/。adminapi、apicontroller、service、repositoryuser、goods、order、content、channel/api/*/adminapi/*/apidoc/服务端采用按访问端、职责层和业务域拆分的目录结构,便于保持控制器轻量、服务职责清晰和查询逻辑集中。
api/ ├─ app/ │ ├─ adminapi/ 后台正式接口入口 │ ├─ api/ 前台正式接口入口 │ ├─ middleware/ 中间件 │ ├─ repository/ 仓储层 │ ├─ service/ 服务层 │ ├─ model/ 数据模型 │ ├─ event/ 事件定义 │ ├─ listener/ 事件监听器 │ ├─ job/ 任务类 │ └─ command/ 命令行入口 ├─ route/ 路由定义 ├─ config/ 配置文件 └─ public/ 对外访问目录
app/ ├─ adminapi/controller/ 后台管理相关接口 ├─ api/controller/ 前台业务相关接口 ├─ service/admin/ 后台应用服务 ├─ service/api/ 前台应用服务 └─ service/core/ 核心业务规则
| 目录 | 作用说明 | 建议写法 |
|---|---|---|
app/adminapi/controller |
后台正式接口入口,负责接收后台管理端请求。 | 控制器保持轻量,只做参数接收、服务调用和响应输出。 |
app/api/controller |
前台正式接口入口,负责用户端公开接口与登录后接口。 | 适合作为接口层,不建议堆叠复杂业务规则。 |
app/service/admin |
后台应用服务层,编排列表、详情、保存和导出等后台流程。 | 适合处理分页、筛选、格式转换和后台操作流程。 |
app/service/api |
前台应用服务层,编排用户端接口流程。 | 适合承接用户端接口流程,但不承担核心业务规则。 |
app/service/core |
核心业务服务层,承接事务、状态流转、幂等和核心业务规则。 | 后台和前台可复用的核心规则优先放在这里。 |
app/repository |
仓储层,负责模型查询、聚合、分页、统计和写库封装。 | 查询复杂度提升后优先下沉到仓储层。 |
list、detail、save、delete 等统一语义。PascalCase,目录按业务域拆分。forceCancel、refreshListTime。adminapi/controller 或 api/controller 正式入口。以下示例以“新增一个后台公告模块”为例,说明服务端从路由到服务层的组织方式。示例用于说明开发结构,实际业务可替换为任意模块。
// route/admin/content.php
use think\facade\Route;
Route::group('content', function () {
Route::get('notice/list', 'app\adminapi\controller\content\Notice@list');
Route::get('notice/detail/:id', 'app\adminapi\controller\content\Notice@detail');
Route::post('notice/save', 'app\adminapi\controller\content\Notice@save');
Route::post('notice/delete', 'app\adminapi\controller\content\Notice@delete');
});
namespace app\adminapi\controller\content;
use app\adminapi\controller\BaseAdminController;
use app\service\admin\content\NoticeService;
class Notice extends BaseAdminController
{
public function list(NoticeService $service)
{
return json($service->getList($this->request->get()));
}
public function save(NoticeService $service)
{
return json($service->save($this->request->post()));
}
}
namespace app\service\admin\content;
use app\repository\content\NoticeRepository;
use app\service\core\content\CoreNoticeService;
class NoticeService
{
public function __construct(
protected NoticeRepository $repository,
protected CoreNoticeService $coreService
) {}
public function getList(array $params): array
{
return $this->repository->page($params);
}
public function save(array $data): array
{
return $this->coreService->saveNotice($data);
}
}
namespace app\service\core\content;
use think\facade\Db;
use app\event\content\NoticeSaved;
class CoreNoticeService
{
public function saveNotice(array $data): array
{
return Db::transaction(function () use ($data) {
$noticeId = 1;
event(new NoticeSaved($noticeId, $data));
return ['code' => 0, 'msg' => '保存成功', 'data' => ['id' => $noticeId]];
});
}
}
// app/event/content/NoticeSaved.php
class NoticeSaved
{
public function __construct(
public int $noticeId,
public array $payload
) {}
}
// app/listener/content/NoticeSavedListener.php
class NoticeSavedListener
{
public function handle(NoticeSaved $event): void
{
// 记录日志、刷新缓存、发送通知
}
}
// app/service/AdminPermissionRegistry.php
[
'content.notice.view' => '查看公告',
'content.notice.save' => '保存公告',
'content.notice.delete' => '删除公告',
]
adminapi 还是 api。后台前端目录结构直接影响后续新增页面时的维护效率。项目当前已经将页面、接口、组件、类型和公共能力分开管理。
admin/src/ ├─ api/ 接口调用层 ├─ components/ 公共组件 ├─ hooks/ 通用 hooks ├─ layouts/ 后台整体布局 ├─ pages/ 业务页面 ├─ router/ 路由配置 ├─ store/ Pinia 状态管理 ├─ style/ 全局样式与 iconfont ├─ types/ 公共类型定义 └─ utils/ 通用工具与请求封装
src/pages/ ├─ admin-user/ 用户管理 ├─ admin-role/ 角色权限 ├─ admin-admin-user/ 管理员管理 ├─ admin-goods/ 商品管理 ├─ admin-content/ 内容管理 ├─ admin-content-category/ 内容分类 ├─ admin-order/ 订单管理 ├─ admin-finance/ 财务流水与支付单 ├─ admin-addon/ addon 模块管理 ├─ admin-addon-vip/ 付费会员套餐与开通记录 ├─ admin-addon-coupon/ 优惠券模板与领取记录 ├─ admin-media/ 素材管理 ├─ admin-system/ 系统设置 ├─ admin-channel/ 渠道中心、支付与通知配置 ├─ admin-operation-log/ 操作日志 ├─ dashboard/ 数据看板 └─ login/ 登录页
| 目录 | 作用说明 | 建议写法 |
|---|---|---|
src/pages/admin-xxx/ |
后台业务页面目录,通常按模块拆分。 | 列表页统一使用 index.vue,编辑页统一使用 edit.vue。 |
src/api/admin-xxx.ts |
后台接口调用层,负责向服务端发送请求并统一返回结构。 | 尽量导出明确的参数类型、保存类型和接口函数。 |
src/components |
公共组件目录,例如图标组件、两行用户信息组件和上传选择器。 | 只放通用组件,不放页面临时逻辑。 |
src/types/common.ts |
公共响应类型与分页类型定义。 | 优先复用 ApiResponse、ListResponse、ItemResponse、PageInfo。 |
src/utils |
公共工具目录,例如日期、金额格式化和请求封装。 | 重复逻辑达到第三次时优先提炼到工具层。 |
template -> script setup lang="ts" -> style scoped lang="less"。searchForm,列表请求统一为 fetchList()。pagination.current / pageSize / total。AppIcon。any。RowItem,表单统一定义 FormState。ListResponse<T>,详情统一使用 ItemResponse<T>。MessagePlugin.success / MessagePlugin.error。npm run lint、npm run stylelint、npm run build:type。以下示例展示后台前端新增页面时的常见组织方式,包括列表页、编辑页、接口调用层和路由接入。
const searchForm = reactive({
keyword: '',
status: undefined,
});
const tableData = ref([]);
const tableLoading = ref(false);
const pagination = reactive({
current: 1,
pageSize: 10,
total: 0,
});
const fetchList = async () => {};
const handleSearch = () => {};
const handleReset = () => {};
const handlePageChange = (pageInfo) => {};
<t-form :data="searchForm" layout="inline" @submit="handleSearch">
<t-form-item name="keyword" label="关键词">
<t-input v-model="searchForm.keyword" placeholder="请输入关键词" />
</t-form-item>
<t-form-item>
<t-button theme="primary" type="submit">
<AppIcon name="iconfont icon-action-search" class="app-icon-gap" />
查询
</t-button>
</t-form-item>
</t-form>
<t-table
:data="tableData"
:columns="columns"
:loading="tableLoading"
:pagination="pagination"
@page-change="handlePageChange"
/>
const formData = reactive({
id: undefined,
title: '',
status: 1,
});
const loadDetail = async () => {
const res = await getNoticeDetail(detailId.value);
Object.assign(formData, res.data || {});
};
const handleSave = async () => {
const res = await saveNotice({ ...formData });
if (res.code === 0) {
MessagePlugin.success('保存成功');
}
};
export type NoticeRow = {
id: number;
title: string;
status: number;
create_time: string | number;
};
export function getNoticeList(params: Recordable<unknown>) {
return request.get({
url: '/notice/list',
params,
});
}
{
path: '/content/notice',
name: 'AdminContentNotice',
component: Layout,
meta: {
title: '公告管理',
icon: 'iconfont icon-menu-content',
permission: ['content.notice.view'],
},
}
服务端权限注册 -> 后台登录返回 permissions -> 前端 store 缓存权限集合 -> 路由 meta.permission 控制页面可见性 -> 按钮级权限控制具体操作 示例权限码: content.notice.view content.notice.save content.notice.delete
<t-button
v-if="userStore.hasPermission('content.notice.save')"
theme="primary"
@click="handleCreate"
>
<AppIcon name="iconfont icon-action-add" class="app-icon-gap" />
新增
</t-button>
用户模块负责平台用户资料、等级、认证和账户能力,是会员体系和账户体系扩展的基础。
支持用户列表、等级维护、实名认证审核、余额调整和余额流水查看。
适合会员等级、用户审核、钱包账户、消费记录等业务场景。
权限模块负责后台菜单访问、页面进入和按钮操作控制,与管理员和角色管理一起构成后台安全体系。
支持角色管理、权限分配、管理员管理、登录鉴权和菜单可见性控制。
适合多角色后台、分级管理、页面权限控制和操作权限控制。
商品模块负责可售内容与展示数据维护,适合用作电商、权益或内容付费类业务的商品基础层。
支持商品列表、商品编辑、上下架、复制和展示信息维护。
适合继续扩展 SKU、库存、促销活动、规格组合和渠道价。
订单与支付模块承担交易主链路,包括下单、支付单管理、退款处理和财务流水等能力。
支持订单管理、支付单管理、退款处理、流水查看和财务相关数据维护。
适合继续扩展售后流程、账单、结算、对账和多业务订单模型。
渠道中心负责统一管理多端渠道配置,并承接支付能力和通知能力的差异化配置。
支持微信小程序、微信公众号、支付宝小程序、H5、APP 五类渠道。
支持接口配置、支付配置、通知配置、模板同步和渠道能力回显。
应用中心用于承接不应直接耦合到核心业务的能力,一期已提供 addon 模块管理、付费会员和优惠券能力,并预留分销、代理、秒杀、抽奖、积分兑换与 AI 能力扩展方式。
统一管理扩展模块的启停、排序和说明,适合作为后续插件化扩展入口。
支持套餐、天数、价格、永久会员、开通记录与权益码配置,前端登录态可直接获取付费会员快照并按权益码统一校验。
支持模板管理、领取记录、付费会员专属限制和订单抵扣,适合作为营销能力的基础模块。
前台应用中心入口只展示已启用模块,便于按运营配置控制用户侧可见范围。
内容、素材与系统模块承担平台公共信息、资源管理和基础配置维护职责,适合作为长期运营配置入口。
支持内容分类、内容管理、素材分组与上传、协议配置、短信邮件参数和基础系统设置。
适合继续扩展帮助中心、专题页、运营位、消息模板和更多系统策略。
权限和菜单需要保持同一套命名和控制逻辑,保证页面访问、菜单显示和按钮操作行为一致。
权限定义 -> 角色绑定权限码 -> 管理员绑定角色 -> 登录返回 permissions -> 菜单、路由、按钮按权限控制
推荐风格: 模块.动作 示例: goods.view goods.save goods.delete channel.config.save
渠道中心用于统一管理多端渠道的接口、支付和通知能力。相关接口说明与调试能力保留在交互式接口文档中,本节仅说明后台使用方式。
| 渠道 | 登录与授权能力 | 支付能力 | 通知能力 |
|---|---|---|---|
| 微信小程序 | 小程序授权登录 | 微信支付 | 小程序订阅消息、短信通知 |
| 微信公众号 | OAuth 授权登录 | 微信支付 | 公众号模板消息、短信通知 |
| 支付宝小程序 | 小程序授权登录 | 支付宝支付 | 短信通知 |
| H5 | 渠道能力开关与登录扩展预留 | 微信支付、支付宝支付 | 短信通知 |
| APP | 渠道能力开关与登录扩展预留 | 微信支付、支付宝支付 | 短信通知 |
渠道中心,选择需要维护的渠道。接口配置 中填写渠道基础信息,如应用标识、密钥和平台参数。支付配置 中按渠道启用可用支付方式并保存支付参数。通知配置 中按业务通知项配置通知方式。项目文档与资源按用途拆分,避免在同一页面重复维护接口内容和界面资源说明。
| 入口 | 用途 |
|---|---|
/docs/ |
项目介绍、使用说明、开发规范、业务功能与开发示例。 |
/apidoc/ |
接口参数、请求体、响应示例、在线调试与鉴权测试。 |
/docs/iconfont/ |
后台本地图标资源预览与图标名称说明。 |
长期维护时建议保持目录、权限、页面和文档的同步更新,减少后期重复维护和残留问题。
adminapi/controller 或 api/controller。lint、stylelint、build:type。